20183413 2019-2020-2 《Python程序设计》实验二

20183413 2019-2020-2 《Python程序设计》实验二报告

课程:《Python程序设计》

班级:1834

姓名:李杰

学号:20183413

实验教师:王志强

实验日期:2020年4月14日

必修/选修:公选课

 

1.实验内容

1.设计一个简单的计算器,内容包括:

  • 简单的四则运算(可同时包含多个加减乘除运算,但不支持含括号的运算)
  • 求模运算
  • 求阶乘
  • 指数运算
  • 角度和弧度的转化
  • 基本三角函数

2.练习条件、循环等基本语句以及函数、类等知识点。

 

2.实验过程及实验结果

四则运算

先设计最简单的四则运算,最先想到的方法是直接输入两个数,再使用算术运算符进行求解,但这样的局限性太大,需要进行两次输入,且只能对两个数进行简单运算,每次运算还要人为选择是哪种运算。所以我打算在输入时直接输入运算式,再判断式子中有什么符号来确定运算类型,最后直接蒋结果输出。这样就需要提取运算符两边的数字,对这两个数字进行运算,可以使用split函数对输入的运算式进行切割,切割后将两个字符串转化为数字进行运算。这样一来函数比较复杂,创建class可以更加简洁明确。

要注意减法时第一个数可能是负数,此时需进行判断,若输入的字符串以 ’-‘ 开头,则从第二位开始截取一个新的字符串进行切割,切割完再加上负号。

class basic:
    '''
    基本四则运算(无法进行带括号的运算)
    '''
    def __init__(self, expression):
        self.expression = expression
​
    def addition(self, expression): #加法
        num = expression.split('+',1)
        return float(num[0]) + float(num[1])
​
    def subtraction(self, expression): #减法
        if expression.startswith('-') :#第一个数字是负数
            expression = expression[1:]
            num = expression.split('-',1)
            num[0] = '-' + num[0]
        else :
            num = expression.split('-',1)
        return float(num[0]) - float(num[1])
​
    def multiplication(self, expression): #乘法
        num = expression.split('*',1)
        return float(num[0]) * float(num[1])
​
    def devision(self, expression): #除法
        num = expression.split('/',1)
        return float(num[0]) / float(num[1])
​
    def calculation(self, expression): #判断运算式为何种运算
        expression = expression.group()
        if '+' in expression:
            return self.addition(expression)
        if '-' in expression:
            return self.subtraction(expression)
        if '*' in expression:
            return self.multiplication(expression)
        if '/' in expression:
            return self.devision(expression)

 


这样一来计算器就显得更加专业了,但是却也只能进行两个数字之间的运算。如果要求多个数字之间的运算结果,就要对运算式进行多次切割,但是因为涉及到四种运算符,不太好操作,所以我决定尝试使用递归函数,对运算式进行迭代运算,这样就能解决多个数字的运算。但是由于四种运算有先后顺序,所以需要先对乘除法进行运算。这里可以使用正则表达式提取高运算级的操作,再从高到低一步步完成运算。

def sorting(self, expression): #按运算顺序计算
        pattern_high =  re.compile('(\d+\.?\d*(\*|\/)+\-?\d+\.?\d*)') #高运算级
        pattern_low = re.compile('(\-?\d+\.?\d*(\+|\-)+\d+\.?\d*)') #低运算级
        if re.search(pattern_high, expression): #递归
            expression = re.sub(pattern_high, self.calculation, expression)
            return self.sorting(expression)
        elif re.search(pattern_low, expression):
            expression = re.sub(pattern_low, self.calculation, expression)
            return self.sorting(expression)
        else:
            expression
            return expression

expression
= input('请输入运算式:') count = basic(expression) result = count.sorting(expression) print('结果为:', result)

 


 

这样就能较好的解决上述问题。但是如果运算式里有括号时,运算顺序被打乱,此时求解比较复杂,我暂时也还没想到比较好的解决方法,因此这个计算器只适用于不包含括号的四则运算。

求模运算与指数运算

因为算数运算符中有直接求余(模)和求幂的运算,所以设计这两种运算时比较简单,为了输入简洁,所以也像上述四则运算一样创建了一个求模的class,将输入的运算式分割后直接求模(幂)。

class mod_function():
    '''
    求模运算
    '''
    def __init__(self,expression):
        self.expression = expression
​
    def calculation(self,expression):
        num = expression.split('%')
        return int(num[0]) % int(num[1])
​
class index_function():
    '''
    指数运算
    '''
    def __init__(self,expression):
        self.expression = expression
​
    def calculation(self,expression):
        num = expression.split('^')
        return int(num[0]) ** int(num[1])
​
​
expression = input('请输入计算式如:x % y\n')
        mod = mod_function(expression)
        result = mod.calculation(expression)
        print('结果为:', result)
​
expression = input('请输入计算式如:x ^ y\n')
        index = index_function(expression)
        result = index.calculation(expression)
        print('结果为:',result)

 

 

求阶乘

求阶乘只需输入一个数,所以不用再创建class和函数,直接涉及一个for循环即可完成。

z = int(input('请输入求阶乘的值:'))
        result = 1
        for i in range(1,z + 1):
            result = result * i
        print('结果为:',result)

 

弧度/角度转换

弧度和角度的互相转换可以通过math函数库里的radians()degrees()来完成,因为只有一个数字输入,所以可以直接调用函数来完成。

degree = float(input('输入角度:'))
        print('结果为:',math.radians(degree))
​
​
rad = float(input('输入弧度:'))
        print('结果为:',math.degrees(rad))

 

 

简单三角函数

简单三角函数(sin、cos、tan)可以在math函数库中找到,但因为输入时包含函数名,所以创建一个class,利用求模运算的方法也可以很快设计好。

要注意因为函数名(如sin)在计算式开头,所以用split切割后第一个字符串是空字符串,所以要对第二个字符串(索引为1)进行运算。另外因为sin等函数的输入为弧度制,但是用户输入一般为角度值,所以要先把输入的角度转化为弧度。

class degree_function():
    '''
    求三角函数(输入为角度)
    '''
    def __init__(self,expression):
        self.expression = expression
​
    def calculation(self,expression):
        #expression = expression.group()
        if 'sin' in expression:
            num = expression.split('sin')
            degree = float(num[1])
            return math.sin(math.radians(degree))
        elif 'cos' in expression:
            num = expression.split('cos')
            degree = float(num[1])
            return math.cos(math.radians(degree))
        elif 'tan' in expression:
            num = expression.split('tan')
            degree = float(num[1])
            return math.tan(math.radians(degree))
​
​
expression = input('请输入计算式:')
        degree_1 = degree_function(expression)
        result = degree_1.calculation(expression)
        print('结果为:',result)

 

 

 

最后加上菜单,通过一个if-elif语句将所有的选项连在一起,大功告成!

代码全文如下:

'''
实验二  计算器

'''

import re
import math

class basic:
    '''
    基本四则运算(无法进行带括号的运算)
    '''
    def __init__(self, expression):
        self.expression = expression

    def addition(self, expression): #加法
        num = expression.split('+',1)
        return str(float(num[0]) + float(num[1]))

    def subtraction(self, expression): #减法
        if expression.startswith('-') :#第一个数字是负数
            expression = expression[1:]
            num = expression.split('-',1)
            num[0] = '-' + num[0]
        else :
            num = expression.split('-',1)
        return str(float(num[0]) - float(num[1]))

    def multiplication(self, expression): #乘法
        num = expression.split('*',1)
        return str(float(num[0]) * float(num[1]))

    def devision(self, expression): #除法
        num = expression.split('/',1)
        return str(float(num[0]) / float(num[1]))

    def calculation(self, expression): #判断运算式为何种运算
        expression = expression.group()
        if '+' in expression:
            return self.addition(expression)
        if '-' in expression:
            return self.subtraction(expression)
        if '*' in expression:
            return self.multiplication(expression)
        if '/' in expression:
            return self.devision(expression)

    def sorting(self, expression): #按运算顺序计算
        pattern_high =  re.compile('(\d+\.?\d*(\*|\/)+\-?\d+\.?\d*)') #高运算级
        pattern_low = re.compile('(\-?\d+\.?\d*(\+|\-)+\d+\.?\d*)') #低运算级
        if re.search(pattern_high, expression): #递归
            expression = re.sub(pattern_high, self.calculation, expression)
            return self.sorting(expression)
        elif re.search(pattern_low, expression):
            expression = re.sub(pattern_low, self.calculation, expression)
            return self.sorting(expression)
        else:
            expression
            return expression

class mod_function():
    '''
    求模运算
    '''
    def __init__(self,expression):
        self.expression = expression

    def calculation(self,expression):
        num = expression.split('%')
        return int(num[0]) % int(num[1])

class index_function():
    '''
    指数运算
    '''
    def __init__(self,expression):
        self.expression = expression

    def calculation(self,expression):
        num = expression.split('^')
        return int(num[0]) ** int(num[1])

class degree_function():
    '''
    求三角函数(输入为角度)
    '''
    def __init__(self,expression):
        self.expression = expression

    def calculation(self,expression):
        #expression = expression.group()
        if 'sin' in expression:
            num = expression.split('sin')
            degree = float(num[1])
            return math.sin(math.radians(degree))
        elif 'cos' in expression:
            num = expression.split('cos')
            degree = float(num[1])
            return math.cos(math.radians(degree))
        elif 'tan' in expression:
            num = expression.split('tan')
            degree = float(num[1])
            return math.tan(math.radians(degree))

menu='''
1--基本四则运算   2--求模运算   3--指数运算   4--求阶乘
5--角度转弧度   6--弧度转角度   7--三角函数(sin cos tan)
0.退出
'''

while(1):
    print(menu)
    a = input('请选择:')
    if a == '1':
        expression = input('请输入运算式:')
        count = basic(expression)
        result = count.sorting(expression)
        print('结果为:', result)
    elif a == '2':
        expression = input('请输入计算式如:x % y\n')
        mod = mod_function(expression)
        result = mod.calculation(expression)
        print('结果为:', result)
    elif a == '3':
        expression = input('请输入计算式如:x ^ y\n')
        index = index_function(expression)
        result = index.calculation(expression)
        print('结果为:',result)
    elif a == '4':
        z = int(input('请输入求阶乘的值:'))
        result = 1
        for i in range(1,z + 1):
            result = result * i
        print('结果为:',result)
    elif a == '5':
        degree = float(input('输入角度:'))
        print('结果为:',math.radians(degree),'rad')
    elif a == '6':
        rad = float(input('输入弧度:'))
        print('结果为:',math.degrees(rad),'')
    elif a == '7':
        expression = input('请输入计算式:')
        degree_1 = degree_function(expression)
        result = degree_1.calculation(expression)
        print('结果为:',result)
    elif a == '0':
        break
    else:
        print('输入错误,请重新输入!')

 

3.实验过程中遇到的问题和解决方法

  • 问题1:在最初设计四则运算时无法进行多个数的复杂运算

          问题1解决方案:一开始打算把运算式中的所有运算符号都切割开,再使用if语句一个个判断,最后得出结果,但是这样很难实现,所以不得不放弃。后查阅资料发现可以使用正则表达式,于是自己尝试写了两个正则表达式提取优先级,最后再迭代运算,就能较好的解决问题。唯一的遗憾是是对含括号的运算束手无策。

  • 问题2:在使用递归函数迭代运算时系统提示出错,无法得出结果

          问题2解决方案:在调试程序后发现,迭代后原本切割后形成的两个字符串还要再进行切割,因此要将运算后得到的结果转化为str型,才能继续进行迭代,而不能直接返回float或者int型的结果。

  • 问题3:一开始进行四则运算时函数太多,显得关系很乱

          问题3解决方案:创建一个class类,将四则运算有关的函数写进类的方法里,这样一来调用函数就更加简便,逻辑更加清晰,后续的其他运算也采用此方法。

其他

  • 在去年学C语言时我也做过设计计算器的实验,当时写的比较简单,而这次老师没有具体要求,所以我希望挑战一下更高难度的(虽然这对于其他大佬来说还是十分简单)。在使用 字符串相关函数对字符串进行切割、截取时,我体会到了python的简洁高效,一些看似不起眼的函数可以实现很强大的功能,这是我以前不敢现象的。在实验过程中我也遇到了不少困难,我买的教材上缺少正则表达式和字符串函数的部分内容,导致我在操作中走了不少弯路,最后通过上网查找才解决了一些问题。python是个巨大的宝藏,我现在认识到的还仅仅是冰山一角,以后还要不断练习、学习新的知识,温故知新,才能更好的掌握这个工具。

码云地址:https://gitee.com/lijiededizhi/new/blob/master/venv/calculation.py

 

 

 

 

 

 

 

20183413 2019-2020-2 《Python程序设计》实验一报告

课程:《Python程序设计》
班级: 1834
姓名:李杰
学号: 20183413
实验教师:王志强
实验日期:2020年4月12日
必修/选修: 公选课

 

1.实验内容

  • 熟悉Python开发环境;
  • 练习Python运行、调试技能;
  • 编写程序,练习变量和类型、字符串、对象、缩进和注释等;
  • 掌握git技能

2.实验过程及结果

安装python开发环境

从群里下载老师上传的python开发环境,包括python解释器、pycharm和pycharm community等(一般用到的是免费的pycharm community),并且按照安装教程进行安装和调试。

 

练习python运行及调试技能

打开pycharm,创建new project,再创建一个新的python.py文件,打开文件,在其中先编写第一个程序:print("人生苦短,我用python!"),编写完后按Ctrl+Shift+F10开始运行,运行结果为输出“人生苦短,我用python!”

 

找到老师上传的小猪佩奇的代码,将代码复制到pycharm上,运行,运行结果为在弹窗上缓缓画出一个小猪佩奇。

调试代码时,先找到调试开始的代码,单击代码左端设置断点,设置好后点击右上角的debug键开始调试,随后点击下一步一步一步进行检测即可找到代码问题所在。

 

编写程序

运用上课学到的内容编写有实际意义的程序练习巩固基本语法。

 

git

在pycharm上绑定git账户后,每创建一个新的文件夹就会在码云库里生成一个新的仓库,每新建一个文件都会在相应的仓库中生成一个新的代码文件,可以将自己编写过的所有代码都储存在仓库里,也可以去其他人的仓库查找他们编写的代码。

按照教程绑定git账户后,每次新建文件时点击弹出的add选项,编写完成后点击VCS-commit,点击确定后再点击VCS-git-push,等待push完成后即可在码云仓库里看到自己的代码了。

 

 

 

 

 

3.实验过程中遇到的问题以及解决方案

  • 问题1:设置断点后不能正常进行debug

          问题1解决方案:上网查询原因,设置相关环境即可

  • 问题2:误删某个文件后无法正常git

          问题2解决方案:新建另一个project,在码云上新建一个仓库即可

 

其他

    • python确实和我以前接触的C语言不一样,更加简便,但是pycharm的操作更加复杂,要多加练习才能够更好的掌握,相信学好了python以后自己的编程能力能够上一个台阶!

posted @ 2020-04-22 17:05  是老李啊  阅读(273)  评论(0编辑  收藏