day18

# review
"""
    复习
    函数式编程:以函数为中心
    功能1():
        相同
        不同1
    功能2():
        相同
        不同2
    功能3():
        相同
        不同3

    变化点1():
         不同1

    变化点2():
         不同2

    变化点3():
         不同3

    通用(参数):
        相同
        # 不同3()
        参数()

    通用(变化点1)

    通用(lambda 参数:方法体)


"""

# demo01

"""
    python内置高阶函数
"""
from common.iterable_tools import IterableHelper


class Skill:
    def __init__(self, id, name, atk, duration, atk_interval):
        self.id = id
        self.name = name
        self.atk = atk
        self.duration = duration
        self.atk_interval = atk_interval

    # 对象 -->  str
    def __str__(self):
        return "%d -- %s -- %.1f -- %.1f --%.1f" % (self.id, self.name, self.atk, self.duration, self.atk_interval)

    # 重写对象比较逻辑
    # def __eq__(self, other):
    #     如果编号相同,就认为相同
    #     return self.id == other.id

list01 = [
    Skill(101, "葵花宝典", 50, 0, 0),
    Skill(102, "降龙十八掌", 80, 12, 1),
    Skill(103, "黯然销魂掌", 90, 15, 0.5),
    Skill(104, "辟邪剑法1", 70, 0, 0),
    Skill(104, "辟邪剑法2", 70, 0, 0),
]

# 需求:找出编号大于102的所有技能
for item in IterableHelper.find_all(list01,lambda item:item.id > 102):
    print(item)

# 1.过滤器
for item in filter(lambda item:item.id > 102,list01):
    print(item)

# 需求:找出技能列表中所有技能编号和技能名称
for item in IterableHelper.select(list01,lambda item:(item.id,item.name)):
    print(item)

#2. 映射
for item in map(lambda item:(item.id,item.name),list01):
    print(item)

# 需求:找出技能列表中获取攻击力最大的技能
print(IterableHelper.get_max(list01,lambda item:item.atk))

# 3. 取最大值max  取最小 min
print(max(list01,key = lambda item:item.atk))


# 需求:对技能列表根据持续时间进行升序排列
# IterableHelper.order_by(list01,lambda item:item.duration)
# for item in list01:
#     print(item)

# IterableHelper.order_by_descending(list01,lambda item:item.duration)
# for item in list01:
#     print(item)

# 4. 排序
#      -- 返回排序后的结果,不改变原有数据。
#      -- 默认升序排列
#      -- 通过reverse=True 进行降序排列
# for item in sorted(list01,key =lambda item:item.duration):
#     print(item)
for item in sorted(list01,key =lambda item:item.duration,reverse=True):
    print(item)


# demo02

"""
  笛卡尔积 全排列
  练习:exercise02
"""
import itertools

# 排列出所有扑克牌 13 * 4  --> 列表(52)
# 扑克牌的数字
list_number = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
# 扑克牌的花色
list_suit = ["红桃", "黑桃", "方片", "梅花"]

# list_poker = []
# for number in list_number:
#     for suit in list_suit:
#         list_poker.append((number, suit))
#
# print(len(list_poker), list_poker)

# for item in itertools.product(list_number,list_suit):
#     print(item)

result = tuple(itertools.product(list_number, list_suit))
print(len(result), result)

# 排列出3个色子可以组成的所有数字6 * 6 × 6   --》 6**n
# 色子(1 -- 6)  6
# list_result = []
# for x in range(1, 7):
#     for y in range(1, 7):
#         for z in range(1, 7):
#             list_result.append((x, y, z))
# print(len(list_result), list_result)

result = tuple(itertools.product(range(1, 7), repeat=3))
print(len(result), result)

# for item in itertools.product(range(1, 7),repeat=10):
#     print(item)




# demo03

"""
    排列
        从n个元素中取出m个元素,并按照顺序进行排列.
        公式:n!  /  (n-m)!
"""
import itertools

# 7 个人 中取3个
# 7 * 6 * 5 * 4 * 3 * 2 * 1
# 4 * 3 * 2 * 1
tuple_person = ("男1号","男2号","男3号","女1号","女2号","女3号","女4号")
print(7 * 6 * 5)
result = tuple(itertools.permutations(tuple_person,3))
print(len(result),result)


# demo04

"""
    组合
        从n个元素中取出m个元素
        不考虑顺序的排列
    练习:exercise04.py
"""

import itertools

# 7 个人 中取3个
tuple_person = ("男1号", "男2号", "男3号", "女1号", "女2号", "女3号", "女4号")
result = list(itertools.combinations(tuple_person, 3))
print(len(result), result)


# demo05

"""
    外部嵌套作用域
"""


def fun01():
    a = 10
    def fun02():
        b = 20
        # print(a)  # 访问外部嵌套作用域中的变量
        # a = 30# 创建了局部变量a
        nonlocal a  # 声明外部嵌套作用域变量
        a = 30  # 再进行修改

    fun02()
    print(a)

fun01()

# demo06

"""
    闭包
        内外函数的执行环境,称之为闭包
        特点:外部函数执行过后,没有立即释放栈帧(等着内部函数使用).
"""


def fun01():
    a = 10
    print("fun01执行喽")
    # 要素1:有内嵌函数
    def fun02():
        # 要素2:访问外部变量
        print("fun02执行喽", a)
    # 要素3:返回内部函数
    return fun02

result = fun01()
result()# 执行fun02

# demo07

"""
    装饰器
    练习:exercise06
"""

def print_func_name(func):
    def wrapper(*args, **kwargs):
        print(func.__name__)
        return func(*args, **kwargs)

    return wrapper

# 增加新功能:打印函数名称
# def print_func_name(func):
#     print(func.__name__)

# print_func_name(print)

@print_func_name
def say_hello():
    print("hello")


@print_func_name
def say_goodbye():
    print("goodbye")


say_hello()
say_goodbye()

# demo08
"""
    装饰器 -- 推导过程
    在不改变旧功能(进入后台,删除订单)基础上,为其增加新功能(验证权限)
    练习:exercise07
"""

def verif_permissions(func):
    # 2. * args 为了解决位置实参个数无限问题
    def wrapper(*args,**kwargs):# * 将实参合为一个元组
        # 新功能
        print("验证权限")
        # 旧功能
        # 3. 内部函数的返回值就是旧功能的返回值
        return func(*args,**kwargs)# * 将实参拆分,与形参对应

    return wrapper

# 旧功能
@verif_permissions# enter_background = verif_permissions(enter_background)
def enter_background(login_id,pwd):
    print(login_id,"进入后台")

@verif_permissions
def delete_order():
    print("删除订单")
    return True

# # 拦截  =  新 + 旧
# enter_background = verif_permissions(enter_background)
#
# delete_order = verif_permissions(delete_order)

# 1.调用的是内部函数
enter_background("abc",pwd = "123")
print(delete_order())





# exercise01
"""
    练习:
        使用内置高阶函数实现:
        1. ([1,1],[2,2,2],[3,3,3])
           获取元组中长度最大的列表
        2. 在老婆列表列表,获取所有名称与身高
        3. 在老婆列表中,获取所有体重大于50的老婆
        4. 对老婆列表,根据身高进行降序排列
        5. 获取所有身高大于1.6的老婆名称和身高.
"""


class Wife:
    def __init__(self, name="", weight=0.0, height=0.0):
        self.name = name
        self.weight = weight
        self.height = height

    def __str__(self):
        return self.name

    def __repr__(self):
        return "Wife(" + self.name + ")"


list01 = [
    Wife("翠花", 60, 1.5),
    Wife("赵敏", 45, 1.7),
    Wife("铁扇公主", 55, 1.65),
    Wife("如花", 40, 1.6),
]

# 1.
tuple01 = ([1, 1], [2, 2, 2], [3, 3, 3])
print(max(tuple01, key=lambda item: len(item)))
# 2.
# 惰性操作 -->  立即操作
result = tuple(map(lambda item: (item.name, item.height), list01))
print(result[-2:])
# 3.
result = tuple(filter(lambda item: item.weight > 50, list01))
print(result)
# 4.
result = sorted(list01, key=lambda item: item.height, reverse=True)
print(len(result), result)
# 5.
for item in map(lambda item: (item.name, item.height), filter(lambda item: item.height > 1.6, list01)):
    print(item)

# 获取满足条件的所有人
# result = filter(lambda item:item.height > 1.6,list01)
# # 获取人的某些信息
# for item in map(lambda item:(item.name,item.height),result):
#     print(item)

# exercise02
# 练习1:在3男,4女中,选出2个人的所有可能性.
# ("男1号","男2号","男3号")
# ("女1号","女2号","女3号","女4号")
import itertools

tuple_man = ("男1号", "男2号", "男3号")
tuple_woman = ("女1号", "女2号", "女3号", "女4号")
result = tuple(itertools.product(tuple_man,tuple_woman))
print(len(result),result)

# exercise03

import itertools

# 练习1: 计算在4张牌中排列4中的可能性
from common.iterable_tools import IterableHelper

tuple_poker = ("红桃3", "黑桃2", "梅花5", "大王")

list_result = list(itertools.permutations(tuple_poker, 4))
print(len(list_result), list_result)

# 练习2:"012345",可以组成多少个不重复的5位偶数
# list_result = list()
# print(len(list_result), list_result)
for item in filter(lambda item: item[0] != "0" and int(item[-1]) % 2 == 0, itertools.permutations("012345", 5)):
    # ('1', '0', '2', '3', '4') -->"10234" --> 10234
    print(int("".join(item)))

# exercise04

import itertools

# 练习1: 计算在4张牌中组合2张中的可能性
tuple_poker = ("红桃3", "黑桃2", "梅花5", "大王")
# for item in itertools.combinations(tuple_poker,2):
#     print(item)

# 练习2:
# 药品调剂
# 分为3种药品,共取出100例粒,要求:没种必须都要有.
# 计算所有调剂方式
# 提示:思考共取出5粒如何实现
contents = 100
for item in itertools.combinations(range(1, contents), 2):
    # item 是 (1, 2) 板子的位置
    #     (2,4)
    for i in range(item[0]):
        print("A药品", end=" ")

    for i in range(item[1] - item[0]):
        print("B药品", end=" ")

    for i in range(contents - item[1]):
        print("C药品", end=" ")

    print()

# exercise05

"""
    闭包应用
         逻辑连续
         装饰器
"""


# 压岁钱
def give_gife_money(money):
    def child_buy(target, price):
        nonlocal money
        if money >= price:
            money -= price
            print("孩子买了%s,花了%.1f钱" % (target, price))

        else:
            print("钱不够了,呜呜呜~")

    return child_buy



action = give_gife_money(10000)
action("变形金刚", 200)
action("天安门模型", 500)
action("手机", 12000)


# exercise06

"""
    在不改变旧功能(进入后台,删除订单)基础上,为其增加新功能(验证权限)
"""
def verif_permissions(func):
    def wrapper(*args, **kwargs):
        print("验证权限")
        return func(*args, **kwargs)
    return wrapper

@verif_permissions
def enter_background():
    print("进入后台")

@verif_permissions
def delete_order():
    print("删除订单")

enter_background()
delete_order()
# exercise07

"""
    在不改变旧功能(fun01,fun02)基础上,为其增加新功能(打印方法执行时间)
    公式:执行时间 = 开始后 - 开始前
"""
import time


def print_execute_time(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        # 旧功能
        result = func(*args, **kwargs)
        stop_time = time.time()
        # 新功能
        print(stop_time - start_time)
        return result

    return wrapper

@print_execute_time
def fun01():
    for i in range(10):
        pass

@print_execute_time# fun02 = print_execute_time(fun02)
def fun02():
    for i in range(1000000):
        pass


fun01()
fun02()



exercise.txt

# review
作业
1. 三合一
2. 当天练习独立完成
3. 每个灯泡都有"",""两种模式,
    请打印出30个灯泡所有可能的模式
4. 年会节目有:
    "舞蹈1","舞蹈2","舞蹈3","相声1","相声2","歌曲1","歌曲2","歌曲3","歌曲4"
   请打印出节目所有排列的方案
   要求:相同节目不能挨着.

5. 阅读:
    程序员的数学
    重构
    HeadFirst 设计模式

 

posted @ 2019-10-06 00:06  晓亮86  阅读(144)  评论(0编辑  收藏  举报