#-*- coding: utf-8 -*-
print("===========函数的定义及调用===========")
#函数的定义及调用
#函数三要素:参数、函数体、返回值
# 函数定义 求正方形的面积
def area_of_square(length_of_side):
square_area = pow(length_of_side,2)
return square_area
#函数调用 函数名(参数)
area = area_of_square(5)
print (area)
#参数的传递
#形参(形式参数):函数定义时的参数,实际上就是变量名
#实参(实际参数):函数调用时的参数,实际上就是变量的值
#位置参数 严格按照位置顺序,用实参对形参进行赋值(关联) 一般用在参数比较少的时候
#形参与实参必须一一对应,一个不能多,一个不能少
def function(x,y,z):
print (x,y,z)
function(1,2,3)
#关键字参数
#打破位置限制,直呼其名的进行值的传递(形参=实参)
#必须遵守实参与形参数量上的一一对应 多用在参数比较多的场合
def function1(x,y,z):
print(x,y,z)
function1(y = 1, z = 2, x = 3)
#位置参数可以与关键字参数混合使用,但是位置参数必须放在关键字参数前面
function1(1,z=2,y=3)
#不能为同一个形参重复传值
def function2(x,y,z):
print(x,y,z)
#function2(1, z=2, x = 3) 报错
#默认参数 在定义阶段就给形参赋值 -- 该形参的常用值
#机器学习库中类的方法里非常常见 调用函数时,可以不对该参数传值
def register(name,age,sex="male"):
print(name,age,sex)
register("andy",18)
#也可以按正常的形参进行传值
register("linzhiling",38,"female")
#默认参数应该设置为不可变类型(数字、字符串、元组)
#不能是可变类型,比如如下所示的列表,列表的地址不发生变化,具有记忆功能
# 但是它里面的内容会发生变化
def function3(ls=[]):
print (id(ls)) #打印ls列表的地址
ls.append(1)
print (id(ls))
print (ls)
function3()
function3()
function3()
#同一个函数我们把形参改成字符串,我们可以看到每次地址都发生来变化,无记忆功能
def function4(ls="Python"):
print (id(ls))
ls += "3.7"
print (id(ls))
print (ls)
function4()
function4()
function4()
#把不确定是否会使用的参数设置成None,让参数变成可选的
def name(first_name,last_name,middle_name=None):
if middle_name:
return first_name+middle_name+last_name
else:
return first_name+last_name
print(name("da","zai"))
print(name("da","zai","jie"))
#4.可变长参数 *args
#不知道会传过来多少参数 *args 该形参必须放在参数列表道最后
def foo(x,y,z,*args):
print (x,y,z)
print (args)
foo(1,2,3,4,5,6) #多余道参数,打包传递给args
#实参打散
def foo1(x,y,z,*args):
print (x,y,z)
print (args)
foo1(1,2,3,[4,5,6]) #[4,5,6]这个列表作为作为元组道一个元素而存在
foo1(1,2,3,*[4,5,6]) #将列表中道元组打散,作为一个个单独的元素
#可变长参数 **kwargs 它的用法和字典有关
def foo2(x,y,z, **kwargs):
print(x,y,z)
print(kwargs)
foo2(1,2,3, a=4,b=5,c=6)#多余的参数,以字典的形式打包传递给kwargs
#字典实参打散
def foo3(x,y,z,**kwargs):
print (x,y,z)
print (kwargs)
foo3(1,2,3,**{"a":4,"b":5,"c":6})
#可变长参数的组合使用
def foo4(*args,**kwargs):
print(args)
print(kwargs)
foo4(1,2,3,a=4,b=5,c=6)
#函数体与变量的作用域
#函数体就是一段只在函数被调用时,才会执行的代码,代码构成与其他代码并无不同
#局部变量 仅在函数体内定义和发挥作用
def multipy(x,y):
z = x*y
return z
multipy(2,9)
#print (z) 这里报错,因为函数执行完毕,局部变量z已经被释放掉了
#全局变量 外部定义的都是全局变量 全局变量可以在函数体直接使用
n = 3
ls = [0]
def multify1(x,y):
z = n*x*y
ls.append(z)
return z
print (multify1(2,9))
#通过global在函数体内定义全局变量
def multipy2(x,y):
global c
c = x*y
return c
multipy2(2,9)
print (c)
#返回值
#单个返回值
def foo5(x):
return x**2
#多个返回值 -- 以元组的形式
def foo6(x = 1):
return 1,x,x**2,x**3
print (foo6(3))
a,b,c,d = foo6(3) #解包赋值
print (a,b,c,d)
#可以有多个return语句,一旦其中一个执行,代表了函数运行的结束
def is_holidy(day):
if day in ["Sunday","Saturday"]:
return "Is holiday"
else:
return "Not holiday"
print ("lalalala damaxiya") #没机会运行
print(is_holidy("Sunday"))
print(is_holidy("Monday"))
#没有return语句,返回值为None
def foo7():
print("我是孙悟空")
res = foo7()
print (res)
print("=================函数式编程=================")
#我们用一个例子解释一下什么是函数式编程
#小A和小B进行比赛,小A每球获胜的概率为55%,小B每球获胜的概率为45%,每局比赛,先赢21球者获胜
#假设进行 n=10000局独立的比赛,小A会获胜多少?(n较大但时候,实验结果≈真实期望)
def main():
#主要逻辑
prob_A, prob_B, number_of_games = get_inputs() #获取原始数据,小A每球获胜概率,小B每球获胜概率,比赛场次
win_A,win_B = sim_n_games(prob_A,prob_B,number_of_games) #获取小A赢了多少场,小B赢了多少场
#print_summary(win_A,win_B,number_of_games) #将获取但结果打印输出
#输入原始数据
def get_inputs():
#输入原始数据
prob_A = input('请输入运动员A的每球获胜概率:')
prob_B = round(1-prob_A,2)
number_of_gamgs = input("请输入模拟但场次(正整数): ")
# print("模拟比赛总次数:",number_of_gamgs)
# print("A 选手每球获胜概率:",prob_A)
# print("B 选手每球获胜概率:",prob_B)
return prob_A,prob_B,number_of_gamgs
#单元测试
prob_A,prob_B,number_of_games = get_inputs()
#print (prob_A,prob_B,number_of_games)
#多场比赛模拟
def sim_n_games(prob_A,prob_B,number_of_gmaes):
#模拟多场比赛但结果
win_A,win_B = 0,0 #初始化A,B获胜但场次
for i in range(number_of_games):
score_A, score_B = sim_one_game(prob_A,prob_B) #获得模拟一次比赛但比分
if score_A > score_B:
win_A += 1
else:
win_B += 1
return win_A,win_B
import random
def sim_one_game(prob_A,prob_B):
#模拟一场比赛但结果
score_A,score_B = 0,0
while not game_over(score_A,score_B):
if random.random() < prob_A:
score_A += 1
else:
score_B += 1
return score_A,score_B
def game_over(score_A,score_B):
return score_A == 21 or score_B == 21
#单元测试 用 asser---断言
#表达式结果为false但时候触发异常
assert game_over(21,8) == True
if __name__ == "__main__":
main()
print("==============匿名函数===============")
#匿名函数 基本形式 lambda 变量:函数体
#常用用法 在参数列表中最适合使用匿名函数 尤其是 key = 搭配
#排序sort() sorted()
ls = [(93,88),(79,100),(86,71),(85,85),(76,94)] #默认根据每一个元组的第一个元素进行升序排列
ls.sort()
print(ls)
#如果我们想要根据每个元组但第二个元素进行排序,则可以使用匿名函数完成
ls.sort(key = lambda x:x[1]) #按照key这个元素设置的量进行排序,每个元素x也就是可迭代对象里的单个元素,根据每个元素的第一个位置(第2个元素)的值进行排序
print (ls)
ls1 = [(93,88),(79,100),(86,71),(85,85),(76,94)]
temp = sorted(ls,key=lambda x:x[0]+x[1],reverse=True) #根据总成绩进行排序
print (temp)
#max() min()
ls2 = [(93,88),(79,100),(86,71),(85,85),(76,94)]
n = max(ls,key=lambda x:x[1]) #找到第二个元素的最大值
print (n)
n = min(ls,key=lambda x:x[1]) #找到第二个元素的最小值
print (n)
print ("============面向对象和面向过程=============")
#面向过程 已过程为中心的编程思想,以“什么正在发生”为主要目标进行编程。 冰冷的 程序化的
#面向对象 将现实生活中的事物抽象成对象,更关注"谁在受影响",更加贴近现实 有血有肉,拟人的(物)化的