sicp_python chap.1 review

内容梳理

这里简单回忆&总结一下第一章的内容

1.1 引言

  • 强调了计算机科学与抽象的联系。
  • Python3的一些简介。
  • Python(编程语言)的基础概念: 语句与表达式、函数、对象、解释器
  • 实践指南——基本的debug方法论。

1.2 编程元素

程序必须为人类阅读而编写,而仅仅是碰巧可以让机器执行。

每门强大的语言都应该拥有用于完成以下任务的机制:

  • 基本的表达式与语句,由语言提供,表示最简单的构建代码块
    • 表达式
      • 调用表达式
    • 库函数
  • 组合的手段,组合简单的元素来构建复杂的元素。
    • 嵌套表达式
      • 求出运算符
      • 求出操作数子表达式
      • 在值为操作数子表达式的参数上调用值为运算符子表达式的函数
      • 图解
    • 嵌套函数
  • 抽象的手段,通过抽象来命名复杂的元素,并将其作为一个整体操作。
    • 名称与绑定
    • 环境
      • 解释器维护某些内存来跟踪这些名称和值的绑定
    • 函数图解
    • 自定义函数(1.3)

1.3 定义新的函数

  • def语句
  • 形参、实参
  • python没有函数重载
  • 环境
    • 图解
      • 全局帧
      • 局部帧与函数调用
  • 命名规范——下划线而非驼峰
    • 永远不要单独使用l(小写L)、O或者I(大写i)
    • 函数名与参数名应该使用描述性的名称
  • 函数式抽象

1.4 实践指南:函数的艺术

如何编写良好的函数

  • 每个函数只应做一个任务,可以使用短小的名称来定义,一行文本来标识。
  • 不要重复劳动(DRY),如果你在复制粘贴一段代码,可能你已经发现了一个使用函数抽象的机会。
  • 函数应该定义的一般一些,并通过(默认)参数来特化它。
  • 文档字符串
    • 描述函数的任务&参数
  • 参数默认值

1.5 控制

语句的值是不存在的,我们用执行而非求值来描述语句。表达式也可以作为语句执行,他们会被求值,但是他们的值会被舍弃。

  • 复合语句
  • 局部赋值(局部变量)
    • 函数作用域
    • 与控制语句结合,提高函数的表现力
    • 将名称赋为间接量,理清复杂表达式的含义
  • 条件语句
  • 迭代语句
  • 测试
    • assert
    • doctest

1.6 高阶函数

作为程序员,我们应该留意识别程序中低级抽象的机会,在它们之上构建并泛化它们来创建更加强大的抽象。

  • 函数作为参数
  • 函数作为一般方法
  • 嵌套函数
    • 词法作用域(定义时而非运行时)
    • 关联环境
    • 调用时局部帧扩展于关联环境
  • 函数作为返回值
    • 局部定义的函数返回时仍持有关联的环境(函数闭包)
  • Lambda表达式
    • lambda表达式中不允许出现赋值或控制语句
  • 函数作为一等公民
    • 带有最少限制的元素被称为具有一等地位
    • 可以绑定到名称
    • 可以作为参数传递
    • 可以作为返回值返回
    • 可以包含在数据结构中
  • 函数装饰器

总结与感悟

环境图解

这是我第一次接触到用图形去解释一些编译的过程与原理,再加上书中对元素解释的也不是很清晰,看起来还是有点吃力的。但渐渐熟悉了之后,确实加强了对原理的理解。

python基础与抽象

可以明显感觉到,这本书讲述python的顺序与逻辑和别的教材不太一样。强调抽象贯穿了整个章节,比如强化函数的概念、强调隔离、在介绍控制语句和内置数据结构前介绍函数…

抽象可能是这本书提到次数最多的概念,也是最着重强调的概念。但是呢,编程终归是一项需要不断实践,在实践中深化认识的技能。还是需要在未来的编程实践中不断的强化自己的理解与认识捏!

python与函数式编程

本书对函数的强调以及python对函数、高阶函数的支持等一度让我以为python是一种函数式语言。

在查阅了一些参考资料之后发现,虽然python对于函数式编程有比较不错的支持,如函数一等公民的身份、高阶函数等等。但尾递归的优化、函数的克里化等问题,确实限制了函数式编程的优雅与效率。再加上Guido本人的看法,以及python使用者并没有大量的使用函数式编程,基本可以认为python可以采用函数式编程的范式,但并不是一种函数式语言。

考虑到python虽然万物皆对象,但len()等函数却不是以方法的形式存在的。再加上python可以用函数去模仿类,类的定义也显得有些别扭(对我来说总感觉很“函数”)。所以我个人感觉python还是更偏向命令式或者函数式吧…

项目——Hog

项目目标

在这个项目中,需要模拟骰子游戏Hog的逻辑并为它开发多种策略。这需要用到控制和高阶函数。

游戏规则

在Hog游戏中,两个玩家轮流行动争取首先达到100分。在每个回合中,当前的玩家选择一些骰子(最多10个)来掷出,他的得分是骰子结果的总和。
同时,游戏还要满足以下的规则:

  • PigOut: 如果掷出1,则本轮得分为1分
  • FreeBacon: 如果选择掷0颗骰子,则获得对手得分中最大的数字+1的分数。
  • HogWild: 如果两个玩家的总分之和是7的倍数,那么当前玩家就会掷出四面骰,而非六面骰。
  • SwineSwap: 如果在一个回合结束时,其中一个玩家的总分正好是另一个玩家的两倍,那么玩家就会交换总分。

项目框架

Hog模块

关键代码

这里展示了模拟一局游戏的逻辑,将函数作为参数的抽象能力是这部分的关键。

def play(strategy0, strategy1, goal=GOAL_SCORE):
    """Simulate a game and return the final scores of both players, with
    Player 0's score first, and Player 1's score second.

    A strategy is a function that takes two total scores as arguments
    (the current player's score, and the opponent's score), and returns a
    number of dice that the current player will roll this turn.

    strategy0:  The strategy function for Player 0, who plays first.
    strategy1:  The strategy function for Player 1, who plays second.
    """
    who = 0  # Which player is about to take a turn, 0 (first) or 1 (second)
    score, opponent_score = 0, 0
    "*** YOUR CODE HERE ***"
    while max(score, opponent_score) < goal:
        # Hog Wild
        dice_type = select_dice(score, opponent_score)
        if who == 0:
            # 对手的得分 FreeBacon
            score += take_turn(strategy0(score, opponent_score), opponent_score, dice_type)
        else:
            opponent_score += take_turn(strategy1(opponent_score, score), score, dice_type)
        who = other(who)
        # Swine Swap
        if 2 * score == opponent_score or opponent_score * 2 == score:
            score, opponent_score = opponent_score, score
    return score, opponent_score  # You may wish to change this line.

项目结果

  1. 模拟游戏逻辑的部分完成了,并通过提供的GUI交互式的测试过。
  2. 游戏胜率评估的部分也完成了,这里用到了嵌套函数以及函数作为返回值。
  3. 游戏的基础策略完成了,包含了利用FreeBacon、SwineSwap等规则的策略。
  4. 最终的策略没有去做,主要还是时间问题。此外,感觉这部分主要是逻辑的问题,与函数抽象关系不大,所以就没去完成这一部分。

项目总结

这个小项目意在让人体会函数抽象。不得不感慨这种写好程序框架,把空位留出来,并且配有相当完善的文档的项目做起来是真的舒畅。

对于这个项目,首先感到的就还是逻辑复用吧,通过将名称与代码段相关联,可以多次复用同样的逻辑。
其次应该是高阶函数的使用了,有效的构造了几个一般函数,通过接受不同的函数参数来实现不同的功能。这种高阶抽象确实让我感受到了快感!
最后是一种隐含的功效吧,抽象带来的逻辑上的隔离。让我在思考问题的时候,有效的简化了心中的模型,将一部分功能简化为了特定输入输出的接口。怎么说呢,这种心智负担的减少,也是抽象带来的强大的表现力的体现吧!

以上。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值