20192426 2019-2020-2「Pythonプログラミング」実験2レポート

コース:「Pythonプログラミング」
クラス:1924
名前:Chen Hanwen
学生ID:20192426
実験教師:Wang Zhiqiang
実験日:2020年4月16日
必須/選択科目:パブリック選択科目

1.実験的な内容

  • 完全なアプリケーションプログラム、加算、減算、乗算、除算などの完全な演算、およびその他の機能を設計して完成させます。
  • 基本的な文法、判断文、ループ文、論理演算などの知識ポイントを調べます。

2.実験プロセスと結果

実験プロセス:

初版:

  1. まず第一に、計算機は式の結果を直接計算でき、得られた結果を操作し続けることができると思うので、2つのケースに分けられます。

    • 新しい計算を実行する

    • 得られた結果を操作し続けます。

  2. 次に、whileループを使用して、計算機が複数の計算を実行できるようにします。実際、上記の2つの状況の違いはそれほど大きくなく、一方の状況が完了すると、もう一方の状況はほぼ完了します。だから、私は最初のケースを終えました

ここでは、ユーザーが入力した操作記号が+-* /%かどうかを判断する判断記号()関数を定義します

def judgesymbol(a):
    if a in ["+", "-", "*", "/", "%", "**"]:
        return 1
    else:
        print("\033[31m请重新输入运算符号!\033[0m")
        return 0

除数が0であるかどうかを判断する裁判官ゼロ()関数を定義します。

def judgezero(a):
    try:
        eval(a)
        return 1
    except ZeroDivisionError:
        print("\033[31m0不能作为除数!请重新输入!\033[0m")
        return 0

この部分の本体は次のとおりです。

while True:	
   if i == 2:
      a = input("请输入第一个操作数:")
      s = input("请输入运算类型:")
      if judgesymbol(s) == 0:
          continue
      b = input("请输入第二个操作数:")
      sum = a+s+b
      if judgezero(sum) == 0:
          continue
      print(sum+"={:g}".format(eval(sum)))
      i = int(input("是否继续输入?(输入0结束,输入1对得出的结果继续操作,输入2进行新的运算)"))

ここでは、eval()関数を使用して式を計算し、「{:g}」を使用しています。Format()を使用して結果に不要なゼロが生成されないようにし、iをループの条件として使用しています。

  1. 最初の部分のコードを変更した直後に、2番目の部分を完了しました。(変更が発生した場所はコードにマークされています)
    while True:
        if i == 1:
     3      sum1 = sum
     4      print("第一个操作数为", eval(sum1))
            a = input("请输入运算类型:")
            if judgesymbol(a) == 0:
                continue
            b = input("请输入第二个操作数:")
     9      sum1 = sum+a+b
            if judgezero(sum1) == 0:
                continue
    12      print("{}".format(eval(sum))+a+b+"={:g}".format(eval(sum1)))
    13      sum = sum1
    14      i = int(input("是否继续输入?(输入0结束,输入1对得出的结果继续操作,输入2进行新的运算)"))
    
  2. コードの最終バージョンは次のとおりです(コードクラウドダイレクト)。
# -*- encoding: utf-8 -*-
'''
文件:    Experiment2.py
时间:    2020/04/11 16:12:24
作者:    20192426 陈瀚文
'''

# 版本一


def judgesymbol(a):
  '''
  判断是否输入的符号是否为+-*/%中的一个
  '''
  if a in ["+", "-", "*", "/", "%", "**"]:
      return 1
  else:
      print("\033[31m请重新输入运算符号!\033[0m")
      return 0


def judgezero(a):
  '''
  功能:判断被除数是否为零,若不为零输出运算结果,否则重新输入
  '''
  try:
      eval(a)
      return 1
  except ZeroDivisionError:
      print("\033[31m0不能作为除数!请重新输入!\033[0m")
      return 0


i = 2
sum = ""
sum1 = ""
while True:
  if i == 0:
      break
  if i == 1:              # 对得出的结果继续操作
      sum1 = sum
      print("第一个操作数为", eval(sum1))
      a = input("请输入运算类型:")
      if judgesymbol(a) == 0:     # 判断符号是否合法
          continue
      b = input("请输入第二个操作数:")
      sum1 = sum+a+b
      if judgezero(sum1) == 0:    # 判断是否进行了除0运算
          continue
      print("{}".format(eval(sum))+a+b+"={:g}".format(eval(sum1)))
      sum = sum1
      i = int(input("是否继续输入?(输入0结束,输入1对得出的结果继续操作,输入2进行新的运算)"))
  if i == 2:          # 对两个数进行运算
      a = input("请输入第一个操作数:")
      s = input("请输入运算类型:")
      if judgesymbol(s) == 0:     # 判断符号是否合法
          continue
      b = input("请输入第二个操作数:")
      sum = a+s+b
      if judgezero(sum) == 0:     # 判断是否进行了除0运算
          continue
      print(sum+"={:g}".format(eval(sum)))
      i = int(input("是否继续输入?(输入0结束,输入1对得出的结果继续操作,输入2进行新的运算)"))

  1. 結果は次のとおりです。

概要:プログラムのバージョン1を長期間使用した後、このプログラムにはまだ多くの欠点があることがわかりました。たとえば、入力する場合、オペランドと式が別々に入力されます。入力が正しくない場合は、再入力する必要があります。これにより、ユーザーは時間を浪費し、プログラムの効率を非効率にし、プログラムが計算集約的でない式を計算するときに暗算時間よりも多くの時間を費やすため、ユーザーに不便をもたらすため、プログラムを最適化するというアイデアを思いつきましたそして第2版を完成させました。


第2版​​(最終版)

  1. コードの最初のバージョンでは、次のように考えました
    。-ユーザーが式全体を直接入力する場合は、eval()関数を使用して式の値を直接検索できます。
    -正規表現を使用して、ユーザーが入力した文字列のオペランドと演算子を分割し、分割の結果に基づいて状況を検討できます
    -このようにすると、三角関数を計算するコードを記述しやすくなります、三角関数を計算する関数を計算機に追加できます
  2. 上記の考えと初版の関連コードに基づいて、reモジュールと数学モジュールをインポートし、最初に4つの算術部分のコードを完成させ、関数splitarg()を定義して、非演算子部分をオペランドと演算子から分離しました
    def splitarg(formula):
        '''
        功能:将数与运算符分离
        '''
        pattern = "[+\-*/%]"
        return re.split(pattern, formula)

関数splitmark()を定義して、演算子をオペランドおよび演算子から分離します

def splitmark(formula):
    '''
    功能:将运算符与数分离
    '''
    pattern = "[0-9]"
    mark = re.split(pattern, formula)
    return list(filter(None, mark))

関数ジャッジ()を定義して、被除数がゼロかどうかを判別します

def judge(formula):
    '''
    功能:判断被除数是否为零,若不为零输出运算结果,否则重新输入
    '''
    try:
        print("{}={:g}".format(formula, eval(formula)))
        return str(eval(formula))
    except ZeroDivisionError:
        print("\033[31m0不能作为除数!请重新输入!\033[0m")
  1. この後、バージョン1のコードを参考にして四つの演算部の機能を完成させましたコードは以下の通りです:

    def simple(result):
        '''
        功能:四则运算+求余运算+乘方
        '''
        while True:
            formula = input()
            arg = splitarg(formula)         # 把表达式以运算符为界分割成列表
            arg = list(filter(None, arg))   # 将列表中的空字符串删掉
            mark = splitmark(formula)       # 把表达式中的运算符分离出来
            if formula == "q":              # 若输入为q,结束循环
                print("                       Bye~")
                return '0'
            elif formula == "c":            # 若输入为c,切换成计算三角函数模式
                return '2'
            elif len(arg) == 1 and mark != []:  # 若输入的表达式只有一个操作数,则默认上一次计算的结果为另一个操作数
                result = result+formula
                result = judge(result)
            else:                           # 正常输入表达式,正常计算
                result = judge(formula)
    
  2. 次に、三角関数の部分が記述されました。mathモジュールによって提供される三角関数はすべてラジアンシステムを使用するため、三角関数の操作中に角度システムをまずラジアンシステムに変換し、結果を逆三角関数の操作中に角度システムに変換する必要があります。 2つを個別に検討すると、コードは次のようになります。

    def trigonometric(result):
        '''
        功能:计算三角函数
        '''
        while True:
            formula = input("请输入表达式:")
            if formula == "q":              # 若输入为q,结束循环
                print("                       Bye~")
                return '0'
            elif formula == "c":            # 若输入为c,切换成计算三角函数模式
                return '1'
            else:
                arg = re.split("[()]", formula)     # 将三角函数表达式以括号为界分割,组成列表
                arg = list(filter(None, arg))       # 除去列表中的空字符串,若输入正确,此时列表的第一项为三角函数名,第二项为数据
                # 判断表达式所计算的是三角函数还是反三角函数
                if len(arg[0]) == 3:                # 三角函数情况
                    arg[1] = eval(arg[1])/180*pi
                    formula1 = eval(arg[0]+"("+str(arg[1])+")")
                    print("{}={:g}".format(formula, formula1))
                elif len(arg[0]) == 4:              # 反三角函数情况
                    formula1 = eval(arg[0]+"("+str(arg[1])+")")*180/pi
                    print("{}={:g}".format(formula, formula1))
    
  3. この時点で、必要なすべての関数が記述され、最後にメイン関数部分が記述されています。

    print('''\033[36m---------------------开始计算---------------------\033[0m\n
    \033[33m--------------------输入q退出---------------------\033[0m\n
    ---------------请直接输入要计算的公式---------------
    
    支持运算类型:
        1.四则运算
        2.求余运算
        3.乘方(用“**”表示,例如2^3表示为2**3)
        4.三角函数计算(直接输入公式,例如:sin(x))
    ''')
    
    mode = input('''请选择模式,输入对应的数字序号:    
        1.普通计算(对应类型1-3)
        2.三角函数(对应类型4)
        0.退出
        ''')
    if mode == '0':
        print("                       Bye~")
    while (int(mode)):      # 当mode="0"时,程序退出
        if mode == '1':     # 当mode="1"时,执行四则运算函数
            print("请输入表达式:(输入q退出,输入c切换模式)")
            result = "0"
            mode = simple(result)
        elif mode == '2':   # 当mode="2"时,执行三角函数计算
            print("请输入表达式:(角度使用角度制,反三角函数请使用形如asin()的形式输出输入q退出,输入c切换模式)")
            result = "0"
            mode = trigonometric(result)
        else:               # 当输入其他值时,报错
            print("\033[31m请正确输入模式序号!\033[0m")
    
  4. コードの最後の2番目のバージョンは次のとおりです(コードクラウドダイレクト)。

# -*- encoding: utf-8 -*-
'''
文件:    Experiment2.py
时间:    2020/04/16 19:20:35
作者:    20192426 陈瀚文
'''

# 版本二

import re
from math import*


def splitarg(formula):
    '''
    功能:将数与运算符分离
    '''
    pattern = "[+\-*/%]"
    return re.split(pattern, formula)


def splitmark(formula):
    '''
    功能:将运算符与数分离
    '''
    pattern = "[0-9]"
    mark = re.split(pattern, formula)
    return list(filter(None, mark))


def judge(formula):
    '''
    功能:判断被除数是否为零,若不为零输出运算结果,否则重新输入
    '''
    try:
        print("{}={:g}".format(formula, eval(formula)))
        return str(eval(formula))
    except ZeroDivisionError:
        print("\033[31m0不能作为除数!请重新输入!\033[0m")


def simple(result):
    '''
    功能:四则运算+求余运算+乘方
    '''
    while True:
        formula = input()
        arg = splitarg(formula)         # 把表达式以运算符为界分割成列表
        arg = list(filter(None, arg))   # 将列表中的空字符串删掉
        mark = splitmark(formula)       # 把表达式中的运算符分离出来
        if formula == "q":              # 若输入为q,结束循环
            print("                       Bye~")
            return '0'
        elif formula == "c":            # 若输入为c,切换成计算三角函数模式
            return '2'
        elif len(arg) == 1 and mark != []:  # 若输入的表达式只有一个操作数,则默认上一次计算的结果为另一个操作数
            result = result+formula
            result = judge(result)
        else:                           # 正常输入表达式,正常计算
            result = judge(formula)


def trigonometric(result):
    '''
    功能:计算三角函数
    '''
    while True:
        formula = input("请输入表达式:")
        if formula == "q":              # 若输入为q,结束循环
            print("                       Bye~")
            return '0'
        elif formula == "c":            # 若输入为c,切换成计算三角函数模式
            return '1'
        else:
            arg = re.split("[()]", formula)     # 将三角函数表达式以括号为界分割,组成列表
            arg = list(filter(None, arg))       # 除去列表中的空字符串,若输入正确,此时列表的第一项为三角函数名,第二项为数据
            # 判断表达式所计算的是三角函数还是反三角函数
            if len(arg[0]) == 3:                # 三角函数情况
                arg[1] = eval(arg[1])/180*pi
                formula1 = eval(arg[0]+"("+str(arg[1])+")")
                print("{}={:g}".format(formula, formula1))
            elif len(arg[0]) == 4:              # 反三角函数情况
                formula1 = eval(arg[0]+"("+str(arg[1])+")")*180/pi
                print("{}={:g}".format(formula, formula1))


print('''\033[36m---------------------开始计算---------------------\033[0m\n
\033[33m--------------------输入q退出---------------------\033[0m\n
---------------请直接输入要计算的公式---------------

支持运算类型:
    1.四则运算
    2.求余运算
    3.乘方(用“**”表示,例如2^3表示为2**3)
    4.三角函数计算(直接输入公式,例如:sin(x))
''')

mode = input('''请选择模式,输入对应的数字序号:    
    1.普通计算(对应类型1-3)
    2.三角函数(对应类型4)
    0.退出
    ''')
if mode == '0':
    print("                       Bye~")
while (int(mode)):      # 当mode="0"时,程序退出
    if mode == '1':     # 当mode="1"时,执行四则运算函数
        print("请输入表达式:(输入q退出,输入c切换模式)")
        result = "0"
        mode = simple(result)
    elif mode == '2':   # 当mode="2"时,执行三角函数计算
        print("请输入表达式:(角度使用角度制,反三角函数请使用形如asin()的形式输出输入q退出,输入c切换模式)")
        result = "0"
        mode = trigonometric(result)
    else:               # 当输入其他值时,报错
        print("\033[31m请正确输入模式序号!\033[0m")

  1. 結果は以下の通りです

3.実験および解決プロセス中に発生した問題

  • 質問1:バージョン1のコードを記述した後、入力が面倒であまり便利ではないことがわかりました

  • 問題1の解決策:バージョン1に基づいてバージョン2のコードを記述し、三角関数を計算する関数を追加します。

  • 質問2:三角関数を計算する関数を記述すると、逆三角関数と三角関数の違いが考慮されないため、エラーが報告されます。

  • 問題2の解決策:ifステートメントを使用して三角関数と逆三角関数を計算する

  • 質問3:モードを調整すると、次のコードが毎回実行され、不便が発生します

  mode = input('''请选择模式,输入对应的数字序号:    
  1.普通计算(对应类型1-3)
  2.三角函数(对应类型4)
  0.退出
  ''')
  • 問題3の解決策:上記のコードは、問題を解決するためにwhileループの外に移動されました

その他(感情、思考など)

  1. 実験は学習状況チェックするのに非常に効果的です。この実験では、まだ十分に把握していないという知識がまだあることがわかりました。同時に、コードの量が特定のレベルに達すると、バグが簡単に見つかりなくなり、バグの修正が非常に重要になることもわかりました。困難であり、デバッグ機能により、コードのどの部分が設計の期待に合わないかを明確に知らせて、コードのエラーを修正できます。
  2. コードを作成するプロセスは、より適切な解決策を見つけ、プログラムの実用性を向上させることを目指して、より思考する必要があります

参考文献

おすすめ

転載: www.cnblogs.com/chw123/p/12717113.html