美文网首页python学习笔记
【笔记】《python语言程序设计》—函数和代码复用

【笔记】《python语言程序设计》—函数和代码复用

作者: Hobbit的理查德 | 来源:发表于2020-03-18 16:47 被阅读0次

    一、前言

    学习就是一个不断的自下而上,自上而下的过程。

    前段时间,学着用python实现网站的数据爬取,隐约get到python的一些语法和用法,感觉就是语法不难,关键在于解决问题的思维。

    这是需求驱动后的学习。接下来,就需要对python进行系统地了解。

    很早之前搜知乎的时候,就搜到MOOC上的一门《python语言程序设计》课程,讲得很好,而且,我还下载了课件,溜了一遍,感觉就挺有趣的。

    趁着有了实战经验,就把这门入门课刷了一遍。果然是门好课!很适合小白入门,并系统学习,整个教学过程循序渐进,深入浅出,提纲挈领,很有意思!

    课程是北京理工大学嵩天老师的《python语言程序设计》课程,现在已经开了11次课了。课程每个小视频短则几分钟,最长也不超过20分钟,不容易劝退。每章讲解有复习回顾及小结,在平台python123上有每章的练习和测试,直接反馈结果,激发继续学下去的兴趣。

    个人感觉,老师说话速度慢了些,调成了2倍速播放,然后,花了大约3天的时间,把所有的视频,课件,练习和测试都刷了一遍,感觉对python的了解更系统了!

    趁热打铁,把每章的知识点和练习、测试再进行整理回顾一下。

    以下内容均来自课程:《python语言程序设计》平台python123,感兴趣的看课程视频,亲自练习,效果更好~

    二、知识点

    1.函数的定义与使用

    1. 函数的理解与定义

      ①一段具有特定功能的,可重用的语句组

      ②一种功能的抽象,一般函数表达特定功能

      ③两个作用:降低编程难度和代码复用

      def <函数名>(<参数(0个或多个>):
          <函数体>
          return <返回值>
      

      ④函数定义时,所指定的参数是一种占位符;如果不经过调用,不会被执行;参数是输入,函数体是处理,结果是输出(IPO)

    2. 函数的使用及调用过程

      ①调用是运行函数代码的方式

      ②调用时要给出实际参数;实际参数替换定义中的参数;函数调用后得到返回值;

    函数调用过程.png
    1. 函数的参数传递

      ①函数可以有参数,也可以没有,但必须保留括号;

      ②函数定义时可以为某些参数指定默认值,构成可选参数;

      ③函数定义时可以设计可变数量参数,即不确定参数总数量

      def <函数名>(<参数>,*b):
          <函数体>
          return <返回值>
      
    可变参数传递.png

    ④函数调用时,参数可以按照位置或名称方式传递;

    #默认参数m为1
    def fact(n,m=1):
        s=1
        for i in range(1,n+1):
            s*=i
        return s//m
    #位置传递
    fact(10,5)
    #名称传递
    fact(m=5,n=10)
    
    1. 函数的返回值

      ①函数可以返回0个或多个结果

      ②可以有return,也可以没有

      ③多个返回结果以元组类型呈现

    多个返回值.png
    1. 局部变量和全局变量

      ①局部变量和全局变量是不同变量:局部变量是函数内部的占位符,与全局变量可能重名但不同;函数运算结束后,局部变量被释放;可以使用global保留字在函数内部使用全局变量;

    规则1.png

    ②局部变量为组合数据类型且未创建,等同于全局变量

    规则2.png
    1. lambda函数

      ①lambda函数返回函数名作为结果

      ②lambda函数是一种匿名函数,即没有名字的函数

      ③使用lambda保留字定义,函数名是返回结果

      ④lambda函数用于定义简单的、能够在一行内表示的函数

      ⑤谨慎使用lambda函数:该函数主要用作一些特定函数或方法的参数;该函数有一些固定使用方式,建议逐步掌握;一般情况,建议使用def定义的普通函数

      <函数名>=lambda<参数>:<表达式>
      

    2.实例7:七段数码管绘制

    绘制效果:

    time_paint.gif
    import turtle,time
    # 绘制数码管间隔
    def drawGap():
        turtle.penup()
        turtle.fd(5)
    # 绘制单段数码管
    def drawLine(draw):
        drawGap()
        turtle.pendown() if draw else turtle.penup()
        turtle.fd(40)
        drawGap()
        turtle.right(90)
    # 根据数字绘制七段数码管
    def drawDigit(digit):
        drawLine(True) if digit in [2,3,4,5,6,8,9] else drawLine(False)
        drawLine(True) if digit in [0,1,3,4,5,6,7,8,9] else drawLine(False)
        drawLine(True) if digit in [0,2,3,5,6,8,9] else drawLine(False)
        drawLine(True) if digit in [0,2,6,8] else drawLine(False)
        turtle.left(90)
        drawLine(True) if digit in [0,4,5,6,8,9] else drawLine(False)
        drawLine(True) if digit in [0,2,3,5,6,7,8,9] else drawLine(False)
        drawLine(True) if digit in [0,1,2,3,4,7,8,9] else drawLine(False)
        turtle.left(180)
        turtle.penup()
        turtle.fd(20)
    # 绘制时间
    def drawDate(date):
        turtle.pencolor('red')
        for i in date:
            if i=='-':
                turtle.write('年',font=('Arial',18,'Normal'))
                turtle.pencolor('green')
                turtle.fd(40)
            elif i=='=':
                turtle.write('月',font=('Arial',18,'Normal'))
                turtle.pencolor('blue')
                turtle.fd(40) 
            elif i=='+':
                turtle.write('日',font=('Arial',18,'Normal')) 
            else:
                drawDigit(eval(i))
    def main():
        turtle.setup(800,350,200,200)
        turtle.penup()
        turtle.fd(-300)
        turtle.pensize(5)
        drawDate(time.strftime('%Y-%m=%d+',time.gmtime()))
        turtle.hideturtle()
        turtle.done()
    main()
    

    3.代码复用与函数递归

    1. 代码复用与模块化设计

      ①代码复用:把代码当成资源进行抽象:代码资源化(程序代码是一种用来表达计算的“资源”);代码抽象化(使用函数等方法对代码赋予更高级别的定义);代码复用(同一份代码在需要时可以被重复使用)

      ②函数和对象(属性和方法)是代码复用的两种主要形式;

      ③模块化设计:通过函数或对象封装将程序划分为模块及模块间的表达;分而治之;

      ④紧耦合和松耦合:前者表示两个部分之间交流很多,无法独立存在;后者表示两个部分之间交流较少,可以独立存在;模块内部紧耦合,模块之间松耦合;

    2. 函数递归的理解

      ①递归:函数定义中调用函数自身的方式;

      ②两个关键特征:(1)链条:计算过程存在递归链条;(2)基例:存在一个或多个不需要再次递归的基例;

    3. 函数递归的调用过程

      ①递归本身是一个函数,需要函数定义方式描述;

      ②函数内部,采用分支语句对输入参数进行判断;

      ③基例和链条,分别编写对应代码;

    4. 函数递归实例解析

      ①字符串反转

      #将字符串s反转后输出
      #第一种
      s[::-1]
      #第二种
      def rvs(s):
          if s=='':
              return s
          else:
              return rvs(s[1:])+s[0]
      

      ②斐波那契数列

      def f(n):
          if n==1 or n==2:
              return 1
          else:
              return f(n-1)+f(n-2)
      

    4.模块4:Pyinstaller库的使用

    1. Pyinstaller库基本介绍

      ①将.py源代码转换成无需源代码的可执行文件;

      ②第三方库,使用pip install pyinstaller安装;

    2. Pyinstaller库使用说明

      ①简单使用:(cmd命令行)pyinstaller -F <文件名.py>

      ②常用参数:

      参数 描述
      -h 查看帮助
      --clean 清理打包过程中的临时文件
      -D,--onedir 默认值,生成dist文件夹
      -F,--onefile 在dist文件夹中只生成独立的打包文件
      -i <图标文件名.ico> 指定打包程序使用的图标(icon)文件

      举例:

      pyinstaller -i curve.ico -F SevenDigitsDrawV2.py

    5.实例8:科赫雪花小包裹

    描述:科赫曲线,也叫雪花曲线。绘制科赫曲线。获得用户输入的整数N,作为阶,绘制N阶科赫曲线。

    下图为3阶科赫曲线。

    科赫雪花小包裹.png
    import turtle
    def koch(size, n):
        if n==0:
            turtle.fd(size)
        else:
            for angel in [0,60,-120,60]:
                turtle.left(angel)
                koch(size/3,n-1)
    def main(level):
        turtle.setup(800,800)
        turtle.penup()
        turtle.goto(-200, 100)
        turtle.pendown()
        turtle.pensize(2)
        turtle.hideturtle()
        koch(300,level)
        turtle.right(120)
        koch(300,level)
        turtle.right(120)
        koch(300,level)
        turtle.done() 
    try:
        level = eval(input("请输入科赫曲线的阶: "))
        main(level)
    except:
        print("输入错误")
    

    三、练习

    1. 实例7:七段数码管绘制

    同上

    2. 实例8:科赫雪花小包裹

    同上

    3. 任意累积

    描述:请根据编程模板补充代码,计算任意个输入数字的乘积。

    注意,仅需要在标注...的地方补充一行或多行代码。

    def cmul(*b):
        m=1
        for i in b:
            m*=i
        return m
    print(eval("cmul({})".format(input())))
    

    4. 斐波那契数列计算

    描述:根据编程模板补充代码,计算斐波那契数列的值,具体功能如下:

    1. 获取用户输入整数N,其中,N为正整数

    2. 计算斐波那契数列的值

    如果将斐波那契数列表示为fbi(N),对于整数N,值如下:

    fbi(1)和fbi(2)的值是1,当N>2时,fbi(N) = fbi(N-1) + fbi(N-2)
    请采用递归方式编写。

    def fbi(n):
        if (n==1) or (n==2):
            f=1
        else:
            f=fbi(n-1)+fbi(n-2)
        return f
    n = eval(input())
    print(fbi(n))
    

    5.汉诺塔实践

    描述:汉诺塔问题大家都清楚,这里不再赘述。

    请补充编程模板中代码,完成如下功能:

    有三个圆柱A、B、C,初始时A上有N个圆盘,N由用户输入给出,最终移动到圆柱C上。

    每次移动步骤的表达方式示例如下:[STEP 10] A->C。其中,STEP是步骤序号,宽度为4个字符,右对齐。

    请编写代码,获得输入N后,输出汉诺塔移动的步骤。

    输入格式

    一个整数

    输出格式

    每个步骤一行,每行参考格式如下:[STEP 10] A->C

    steps = 0
    def hanoi(src, des, mid, n):
        global steps
        if n == 1:
            steps+=1
            print("[STEP{:>4}] {}->{}".format(steps, src, des))
        else:
            hanoi(src,mid,des,n-1)
            steps+=1
            print("[STEP{:>4}] {}->{}".format(steps, src, des))
            hanoi(mid,des,src,n-1)
    N = eval(input())
    hanoi("A", "C", "B", N)
    

    四、测试

    1.选择题

    1. 以下选项不是函数作用的是:

      A 复用代码

      B 提高代码执行速度

      C 降低编程复杂度
      D 增强代码可读性

    函数不能直接提高代码执行速度。

    1. 下列程序的输出结果为:
    def f(a,b):
      a=4
      return  a+b
    def main():
      a=5
      b=6
      print(f(a,b),a+b)
    main()
    

    A 10 11

    B 11 10

    C 11 11

    D 10 10

    这里没有全局变量,都是函数局部变量的运算。

    1. 以下关于Python函数说法错误的是:
    def func(a,b):
      c=a**2+b
      b=a
      return c
    a=10
    b=100
    c=func(a,b)+a
    

    A 该函数名称为func

    B 执行该函数后,变量a的值为10

    C 执行该函数后,变量c的值为200

    D 执行该函数后,变量b的值为100

    这里没有全局变量,请在IDLE中执行代码观察结果。

    1. 以下关于函数调用描述正确的是:

      A 函数和调用只能发生在同一个文件中

      B 自定义函数调用前必须定义

      C Python内置函数调用前需要引用相应的库

      D 函数在调用前不需要定义,拿来即用就好

    函数调用前必须已经存在函数定义,否则无法执行。

    Python内置函数直接使用,不需要引用任何模块。

    1. 以下关于模块化设计描述错误的是:

      A 应尽可能合理划分功能块,功能块内部耦合度低

      B 应尽可能合理划分功能块,功能块内部耦合度高

      C 高耦合度的特点是复用较为困难

      D 模块间关系尽可能简单,模块之间耦合度低

    模块内高耦合、模块间低耦合。

    1. 以下对递归描述错误的是:

      A 递归程序都可以有非递归编写方法

      B 书写简单

      C 一定要有基例

      D 执行效率高

    递归不提高程序执行效率。

    任何递归程序都可以通过堆栈或队列变成非递归程序(这是程序的高级应用)。

    1. 以下关于函数说法错误的是:

      A 函数可以看做是一段具有名字的子程序

      B 对函数的使用必须了解其内部实现原理

      C 函数通过函数名来调用

      D 函数是一段具有特定功能的、可重用的语句组

    调用函数不需要知道函数内部实现原理,只需要知道调用方法(即接口)即可。

    1. 哪个选项对于函数的定义是错误的?

      A def vfunc(*a,b):

      B def vfunc(a,b):

      C def vfunc(a,*b):

      D def vfunc(a,b=2):

    def vfunc(a, b) 是错误的定义:a表示可变参数,可变参数只能放在函数参数的最后。

    1. 关于return语句,以下选项描述正确的是:

      A 函数中最多只有一个return语句

      B return只能返回一个值

      C 函数可以没有return语句

      D 函数必须有一个return语句

    函数可以包含0个或多个return语句

    1. 以下关于递归函数基例的说法错误的是:

      A 递归函数必须有基例

      B 递归函数的基例决定递归的深度

      C 递归函数的基例不再进行递归

      D 每个递归函数都只能有一个基例

    每个递归函数至少存在一个基例,但可能存在多个基例。

    2.程序设计题

    1. 随机密码生成

    描述:补充编程模板中代码,完成如下功能:

    以整数17为随机数种子,获取用户输入整数N为长度,产生3个长度为N位的密码,密码的每位是一个数字。每个密码单独一行输出。

    产生密码采用random.randint()函数

    import random
    def genpwd(length):
        a=10**(length-1)
        b=10**length-1
        return '{}'.format(random.randint(a,b))
    length = eval(input())
    random.seed(17)
    for i in range(3):
        print(genpwd(length))
    
    1. 连续质数计算

    描述:补充编程模板中代码,完成如下功能:

    获得用户输入数字N,计算并输出从N开始的5个质数,单行输出,质数间用逗号,分割。

    注意:需要考虑用户输入的数字N可能是浮点数,应对输入取整数;最后一个输出后不用逗号。

    def prime(m):
        for i in range(2,m):
            if m % i == 0:
                return False
        return True
    
    n = eval(input())
    n_ = int(n)
    n_ = n_+1 if n_ < n else n_
    count = 5
    
    while count > 0:
        if prime(n_):
            if count > 1:
                print(n_, end=",")
            else:
                print(n_, end="")
            count -= 1 
        n_ += 1
    

    这个代码注意:
    (1) 需要对输入小数情况进行判断,获取超过该输入的最小整数(这里没用floor()函数);
    (2) 对输出格式进行判断,最后一个输出后不增加逗号(这里没用.join()方法)。

    【笔记】《python语言程序设计》—Python基本语法元素

    【笔记】《python语言程序设计》—Python基本图形绘制

    【笔记】《python语言程序设计》——基本数据类型

    【笔记】《python语言程序设计》——程序的控制结构

    【笔记】《python语言程序设计》——函数和代码复用

    【笔记】《python语言程序设计》——组合数据类型

    【笔记】《python语言程序设计》——文件和数据格式化

    【笔记】《python语言程序设计》——程序设计方法学

    【笔记】《python语言程序设计》——python计算生态概览

    相关文章

      网友评论

        本文标题:【笔记】《python语言程序设计》—函数和代码复用

        本文链接:https://www.haomeiwen.com/subject/wircyhtx.html