- images
- results
- .gitignore
- 1.1概论.ipynb
- 1.2 环境配置.pdf
- 1.3数据类型.ipynb
- 1.4 人机交互.ipynb
- 1.5 对象与变量.ipynb
- 1.6 编码与命名规范.ipynb
- 2.1 数值类型.ipynb
- 2.2 数值类型转换.ipynb
- 2.3 数值元算.ipynb
- 2.4常用数学运算函数.ipynb
- 2.5 math 模块及其应用.ipynb
- 2.6.1 逻辑值测试.ipynb
- 2.6.2 成员运算.ipynb
- 2.6.3 比较运算.ipynb
- 2.6.4 布尔运算.ipynb
- 2.6.5 运算优先级.ipynb
- 2.ipynb
- 3.1 流程控制结构.ipynb
- 3.3.1 for 循环语句.ipynb
- 3.3.3 rang.ipynb
- 3.3.3 while 循环语句.ipynb
- 3.4 and 3.5 分支结构和条件.ipynb
- 3.6 and 3.7 .ipynb
- 3.9 异常处理.ipynb
- 4 函数和模块化编程.ipynb
- 4.1 函数的定义、调用与返回值.ipynb
- 4.2 函数的参数传递.ipynb
- 4.3 变量的作用域.ipynb
- 4.4 匿名函数.ipynb
- 4.5 递归.ipynb
- 4.6 内置函数.ipynb
- 4.7 模块化程序设计.ipynb
- 5.1 序列通用操作.ipynb
- 5.1.1 索引.ipynb
- 5.1.2 切片.ipynb
- 5.1.3 序列拼接与重复.ipynb
- 5.1.4 成员测试.ipynb
- 5.2.1 字符串的创建.ipynb
- 5.2.2 字符串常量.ipynb
- 5.2.4 字符串的遍历.ipynb
- 5.2.5 文件遍历.ipynb
- 5.2.6 字符串的处理方法.ipynb
- 5.2.7 字符串格式化.ipynb
- 5.2.8 转义字符.ipynb
- 5.3 random 模块及其应用.ipynb
- 6.1 元组.ipynb
- 6.2 列表.ipynb
- 6.2.1 列表的创建.ipynb
- 6.2.2 列表的更新.ipynb
- 6.2.3 列表的删除.ipynb
- 6.2.4 列表的排序.ipynb
- 6.2.5 列表赋值与复制.ipynb
- 6.2.6 列表推导式.ipynb
- 6.2.8 常用内置函数.ipynb
- 6.2.9 列表嵌套及其排序.ipynb
- 6.3 列表综合应用.ipynb
- 7.1.1 集合的创建.ipynb
- 7.1.2可变集合类型的操作.ipynb
- 7.1.3 成员关系.ipynb
- 7.1.4 集合关系.ipynb
- 7.1.5 集合运算.ipynb
- 7.2.1 字典创建.ipynb
- 7.2.2 获取字典值.ipynb
- 7.2.3 修改字典值.ipynb
- 7.2.4内置函数与方法.ipynb
- 7.2.5字典排序输出.ipynb
- 7.3 集合与字典的应用.ipynb
- 8 中 numpy 概述.ipynb
- 8 中panda 库.ipynb
- 8.1 文件的打开与关闭.ipynb
- 8.2 文件读写操作.ipynb
- 8.3 文件的应用.ipynb
- 8.4 numpy 文件操作.ipynb
- 8.4.2 and 3.ipynb
- 8.5.1 pandas文件读写.ipynb
- 8.5.2 and 3 and 4.ipynb
- 9.1 matplotlib 线性图.ipynb
- 9.1.5 数据文化绘图.ipynb
- 9.2 非线性图.ipynb
- 9.3 词云.ipynb
- _overview.md
- _readme.ipynb
- coding_here.ipynb
- dream.png
- score.txt
- score_total.csv
- 成绩分析综合.json
4.7 模块化程序设计.ipynb @master — view markup · raw · history · blame
4.8 模块化程序设计¶
4.8.1 程序设计方法¶
Python支持__面向对象__的程序设计方法,也支持__面向过程__的程序设计思想。
__面向对象程序设计__的核心是__对象__,是把数据及数据的操作方法放在一起,作为一个相互依存的整体。对同类对象抽象出共性,形成__类__。类中大多数数据,只能用本类的方法进行处理。类通过__接口__与外界发生关系,对象与对象之间通过__消息__进行通信。
__面向对象程序设计__的优点是可扩展性高,适用于用户需求经常变化的场景,如互联网应用、游戏、企业内应用等。其缺点是编程复杂度高,不容易掌握。
__面向过程程序设计__分析出解决问题所需的步骤,然后再用函数把这些步骤一步一步实现,使用时一个一个依次调用即可。面向过程其实是最为实际的一种思考方式,从上往下逐步求精,所以面向过程最重要的思想是模块化设计方法。
当程序规模不是很大时,程序的流程很清楚,按照模块与函数的方法可以很好地组织。对于一般的计算问题和数据处理问题,面向过程的方法会体现出相当的优势。本书的后续内容都是按照面向过程的程序设计思想组织的。
面向过程的程序设计方法,需要合理地应用函数将程序划分为不同的功能单元,分别用不同的函数和模块实现,通过函数的调用和模块的导入实现整体功能。 函数的应用,可以让程序代码扁平化、逻辑更加简单清晰,简化代码的编写、增加代码的可读性和可维护性。
实例4.4 简单计算器
设计一个简单计算器的程序,命名为Calc.py,可以实现简单的加、减、乘、除、整除和幂运算。
#Calc.py
def add(a,b): #加法运算函数
return a + b
def subtract(a,b): #减法运算函数
return a - b
def multiply(a,b): #乘法运算函数
return a * b
def divide(a,b): #除法运算函数
if b == 0: #考虑0为除数的情况
return 'Divided by zero'
else:
return a / b
def divide_no_remainder(a,b): #整数除法运算函数
if b == 0: #考虑0为除数的情况
return 'Divided by zero'
else:
return a // b
def power(a,b): # 幂运算函数
result = 1
for i in range(1,b+1):
result = result * a
return result
if __name__ == '__main__': #当本文件不作模块,被其它程序导入时,下面的代码会被执行
m = eval(input()) #输入第一操作数,可以是整数或浮点数
sign = input() #输入操作符:"+"、"-" 、"*" 、"/" 、"//"、 "**"
n = eval(input()) #输入第二操作数,可以是整数或浮点数
if sign == '+': #当运算符为*时,调用加法函数
print(add(m,n))
elif sign == '-': #当运算符为-时,调用减法函数
print(subtract(m,n))
elif sign == '*': #当运算符为*时,调用乘法函数
print(multiply(m,n))
elif sign == '/': #当运算符为/时,调用除法函数
print(divide(m,n))
elif sign == '//': #当运算符为//时,调用整除函数
print(divide_no_remainder(m,n))
elif sign == '**': #当运算符为**时,调用幂函数
print(power(m,n))
从代码量来看,行数有所增加,但从逻辑上看,程序的结构变得更加清晰。每个函数只实现简单的加、减、乘、除、整除和幂运算中的一种功能,主程序只实现输入、判断和输出,根据输入的不同运算符,调用不同的函数进行处理,程序更为扁平、逻辑也更清晰。
4.8.2 模块¶
通过定义函数的形式将功能封装,可以实现程序设计的模块化。__模块(module)__用来从逻辑上组织Python代码,本质就是扩展名为.py的文件,主文件名为对应的模块名。
Python本身就内置了很多非常有用的模块(__标准库__),这些模块__可以直接使用__。 模块包括标准库、开源模块(第三方库)和自定义模块。
下面的代码导入了__标准库__math模块,使用math模块的pow()进行幂运算。
import math # 导入math库
print( math.pow( 2, 0.5)) # 使用math库的pow()函数计算2的0.5次幂
Python中除了内置大量的标准库外,还有大量的__第三方库__。这些库__安装后__可以直接使用import导入并使用其中的功能模块,极大地简化了编程难度。
如下假定系统已经安装了名为numpy的第三方库,下面的代码导入该库并使用numpy.linspace()函数生成指定区间内的等差数列。
import numpy as toch # 导入第三方库numpy,取别名为np
print( np.linspace(0,100,21)) # 生成[0,100]内由21个数构成的等差数列,并输出
若自己定义的函数需要经常被调用,就可以定义一个模块(__自定义模块__),将函数定义写在模块里,下次使用这些函数时先导入这个模块,就可以调用模块中自定义的函数了。
导入模块的方法如下:
import 模块名 as 模块别名
如果自定义模块与当前程序文件处于同一目录下,则可以使用下面的语句导入模块:
from 模块名 import 类名或函数名
自定义模块与当前程序文件不在同一目录下时,可以在模块名前加上目录名。
__自定义模块__的方法是把需要反复调用的代码定义为函数,将输入、输出和调用函数的语句放到 if name == 'main': 分支下面。例如,将输出小于n的全部素数的程序定义为一个模块,可以将“例4.2素数函数”里的代码做如下修改后保存为__myPrime.py文件__。
#文件 myPrime.py
def is_prime(n):
"""接收正整数n,判断是否为素数,返回布尔值"""
if n < 2:
return False # 0和1不是素数
for i in range(2, n): # 遍历2 ~ n-1中的数
if n % i == 0: # 若存在因子则不是素数
return False # 不是素数时返回False
else: # for匹配,当i==2时也进入该子句
return True # 素数时返回True
if __name__ == '__main__':
num = int(input()) # 读入一个正整数
for i in range(num): #输出 0 ~ num-1 范围内的素数
if is_prime(i): # 调用函数
print(i,end=' ')
__直接运行myPrime.py文件__ 时,它的 name 属性值为'main',此时执行if name == 'main': 分支里的语句,等待用户输入正整数num,输出小于num的所有素数。
将__myPrime.py文件作为模块__ 时,需要导入模块名myPrime,此时它的 name 属性值为模块名,不执行if分支。
用这种方法编写的程序可以作为模块导入,程序中定义的函数可以很方便地被其它程序引用。
将myPrime.py文件放到当前文件夹下,导入myPrime模块,利用其中的is_prime()函数实现:输入n,输出不大于n的所有回文素数。
回文素数:指一个数既是素数又是回文数。例如131,既是回文数又是素数,因此131是一个回文素数。
# 鉴于educoder平台的特点,请先运行本行命令将myPrime.py放到当前文件夹下
!tar -xvf /data/bigfiles/44c570f4-2027-4e63-883c-695a90377873.tar
# 回文素数
# 用户输入一个正整数 n, 在一行内从小到大输出不大于n的回文素数,空格分隔。
import myPrime #导入当前路径下的myPrime模块
def palindromic(num):
"""接收一个数字为参数,判定其是否为回文数,返回布尔值。"""
if str(num) == str(num)[::-1]:
return True
else:
return False
def palindromic_prime(number):
"""接收一个正整数参数number,遍历从0到number之间的所有整数,
若某个数是素数,且转为字符串后是回文字符串,则称其是回文素数。
找出并在同一行中从小到大输出不大于number的所有回文素数,每个输出后加一个空格,
函数无返回值。
"""
for i in range(number + 1 ): # 遍历小于n的整数
if palindromic(i) and myPrime.is_prime(i):
print(i, end=' ') # i为回文素数时输出i
if __name__ == '__main__':
n = int(input())
palindromic_prime(n)
# 运行时,输入: 200
# 输出: 2 3 5 7 11 101 131 151 181 191
练一练
将myPrime.py文件放到当前文件夹下,模仿上面的代码,导入myPrime模块分别完成:1. 输出不大于n的所有反素数,2. 验证哥德巴赫猜想(读入偶数n,将其表示为 n = p + q 的形式,其中p、q均为素数)。
提示: 1.反素数:是指一个非回文数,它和它的逆序数同时是素数。例如13,它自身不是回文数,而13和31都是素数。
2. 哥德巴赫猜想:任何一个大于2的偶数,总能表示为两个素数之和
</font>