1901020029-自学训练营MIT6.0001Day11~20

学员信息

  • 学号:1901020029
  • 学习内容:MIT6.0001课程打卡11-20天
  • 学习用时:16.5

学习笔记

第11天:20190704

学习时间:1小时
学习内容:MIT Lecture 6(主题:递归,字典)(15min-25min) + PPT(p15-p20)
学习收获:
1、复习中学学过的数学归纳法:证明与自然数n有关的数学陈述,需分两步验证。先证明当n取最小值时,命题成立;然后假设n=k时命题成立,那么能证明n=k+1时,命题也成立,则两步验证综合起来,可以推出对一切自然数n,命题都成立。
2、同样的逻辑可以应用到递归函数,递归设计也是递推原理,在整个程序中,反复实现同一个原理。
3、经典的汉诺塔案例,用递归思维来写出代码,简洁好看。

1
2
3
4
5
6
7
8
9
10
def printMove(fr, to):
print('move from ' + str(fr) + ' to ' + str(to))

def Towers(n, fr, to, spare):
if n == 1:
printMove(fr, to)
else:
Towers(n-1, fr, spare, to)
Towers(1, fr, to, spare)
Towers(n-1, spare, to, fr)

4、要学习的重点:遇到问题时,如何递归地思考解决方案,如何将问题分解成更小版本的同样的问题。

第12天:20190705

学习时间:1小时
学习内容:MIT Lecture 6(主题:递归,字典)(25min-33min) + PPT(p21-p39)
学习收获:
1、理解斐波那契数列,它是两个递归调用,有两个基本案例。

1
2
3
4
5
6
7
def fib(x):
“““assumes x an int >=0
returns Fibonacci of x”””
if x ==0 or x ==1:
return 1
else:
return fib(x-1) + fib(x-2)

2、非数问题的递归思考,关于回文,递归代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def isPalindrome(s):

def toChars(s):
s = s.lower()
ans = ''
for c in s:
if c in 'abcdefghijklmnopqrstuvwxyz':
ans = ans + c
return ans

def isPal(s):
if len(s) <= 1:
return True
else:
return s[0] == s[-1] and isPal(s[1:-1])

return isPal(toChars(s))

3、理解“分而治之”的智慧:递归算法通过将难题打破分解成一系列子问题,子问题比原始问题容易解决,并且子问题的解决可以被组合起来解决原始问题。

第13天:20190706

学习时间:1小时
学习内容:MIT Lecture 6(主题:递归,字典)(33min-48min) + PPT(p40-p58)
学习收获:
1、终于学到这节课的最后一部分了,关于字典数据类型。
2、字典以“键 : 值”(“key:value”)对的形式成对存在;用{ }呈现;每对“key:value”之间用“,”分隔;检索是通过“key”来访问“value”,如果“key”不存在,则报错。
3、字典的操作:
3.1、添加键值对用 dict[key] = value;
3.2、删除键值对用 del(dict[key])
3.3、查询dict中是否有key,用key in dict,如果有返回True,没有返回False;
3.4、用dict.keys()返回dict中的所有的keys组成的元组,用dict.values()返回dict中所有values组成的元组。
4、字典的特征:
4.1、值可以是任何类型(可变的和不可变的);可以是重复的;可以是列表甚至是另一个字典。
4.2、键必须是独一无二的;是不可变类型;浮点类型做键时需仔细
4.3、字典是无序的。
5、字典在捕获中间值时可以极大的提高效率,最后的这块斐波那契代码案例理解不了,只能先记住字典有这个功用。

第14天:20190708

学习时间:1.5小时
学习内容:MIT Lecture 7前20分钟(testing、debugging)+ PPT(1-17)
学习收获:
1、周末去外地参加大学宿舍同窗20年聚会,20年没见了,激动开心外加感慨良多,一直在路上,昨天未打卡。
2、回归常态学课,是Ana老师,开心!第7节讲程序的测试和调试,测试是找出程序中的错误,调试则是修复未按预期工作的程序。
3、学会防御性编程:给函数写说明书、模块化程序、检查输入输出条件,用测试和调试达成目标。
4、什么时候进行测试?保证代码去除语法、静态语义错误,可以运行;针对输入,有一套预期的结果时,即可进行测试。
5、测试的执行:
单元测试:测试每一个独立单元,每一个函数是否正常工作。
回归测试:发现bug,对bug进行测试,抓住再次引入的错误。
集成测试:测试整个程序能否按预期运行。
6、具体的测试方法:
直观的界定问题的自然边界;
如果没有自然边界,可以进行随机测试;
黑盒测试:通过说明书探索测试路径;
白盒测试:通过内部代码探索测试路径;
7、常见错误类型:IndexError、TypeError、NameError、SyntaxError
8、不要做的事:写整个的程序、测试整个的程序、调试整个的程序。
9、要做的事:写一个函数、测试函数调试函数;写一个函数,测试函数调试函数;一直这样直到进行集成测试。
10、不要直接修改代码,记住bug位置,测试代码,忘记bug位置或修改了哪些代码,然后恐慌;而是要备份代码后,再修改代码,备注潜在的bug,测试代码,对比新旧版本。养成好习惯很重要。

第15天:20190709

学习时间:2小时
学习内容:MIT Lecture 7后20分钟(EXCEPTIONS, ASSERTIONS)+PPT(18-35)
学习收获:
1、尝试看英文字幕理解课程,还是有难度,那层玻璃纸还是有点厚。
2、异常(EXCEPTIONS)的类型:IndexError、TypeError、NameError、SyntaxError、AttributeError、ValueError、IOError
3、Python代码处理异常的方法:
3.1、使用try-except代码块,一旦try代码块内抛出异常,直接跳到except代码块执行程序;
3.2、可以用各自独立分开的except子句来处理特殊类型的异常,比如在try代码块后分别跟except ValueError:、except ZeroDivisionError:、except:三个代码块来实现;
3.3、使用else:,在try代码块执行结束没有异常出现时执行else body;
3.4、使用finally:,finally body总是在try,else和except子句之后执行,对于清除代码有用;
3.5、把异常当作控制流,当不能产生符合函数规范的结果时,用raise语句引发一个异常。raise
4、断言(ASSERTIONS)
4.1、使用assert语句确保程序状态符合预期;
4.2、如果不符合预期,assert语句会引发一个AssertionError异常;
4.3、断言是非常好的防御性编程工具。
存在的问题:
1、想了好几天要开始做psets了,心理上总有点逃避,没了外界约束(训练营),大脑总想偷懒。
2、理解课程开始变的很慢,一节课要反复听,才能写出一点收获,课程里的example都没有仔细理解。
3、do excises、do excises、do excises

第16天:20190710

学习时间:2小时
学习内容:MIT Lecture 8(OOP)+PPT(1-9)
学习收获:
1、理解对象objects:
Python支持多种数据,每种数据是一个对象,每个对象有:一种类型;一种内部数据表示法;一套与对象交互的程序。并且一个对象是一种类型的实例。
2、理解面向对象编程OOP:
Python中的一切都是对象(有一种类型),可以创造某种类型的新对象,可以操作对象,可以破坏对象。
3、理解什么是对象?
对象是一种数据抽象,通过数据属性获得内部表达,通过方法(程序/函数)实现与对象的交互,定义行为但是隐藏细节。
4、理解OOP的优点:
将数据及对数据的操作捆绑在一起形成很好的交互;分而治之,可以分别对每个类进行操作和测试,增加模块性减少复杂性;类使代码容易重复使用。
5、用类可以创造和使用自己的类型:
注意区分创造一个类和使用类的实例的不同,创造类包括定义类的名称、定义类的属性;使用类包括创造新的对象实例,对实例进行操作。
6、使用class关键词定义一个新类型:
例如:class Coordinate(object):
7、什么是属性?
数据和程序属于类;数据属性是将数据看作组成类的其它对象,比如坐标是两个数字的组合;方法是程序属性,想象方法是函数,只和这个类工作,如何与对象交互,比如你可以在两个坐标对象之间定义一个距离,但是在两个列表对象之间定义距离就没有意义。

第17天:20190711

学习时间:2小时
学习内容:MIT Lecture 8(OOP)+PPT(10-20)+ps0(1-3)
学习收获:
1、定义如何创建类的实例:
1.1、首先不得不定义如何创建对象的实例
1.2、使用特殊方法init来初始化某种数据属性,例如在坐标类下:

1
2
3
4
5
6
class Coordinate(object):
def init(self,x,y):
self.x = x
self.y = y
c = Coordinate(3,4)
print(c.x)

1.3、一个实例的数据属性被叫做实例变量
1.4、不用为self提供参数,Python自动完成
2、什么是方法?
2.1、程序属性,像是函数仅在类中工作
2.2、Python总是把对象作为第一个参数,惯例用self做所有方法的第一个参数名
2.3、“.”操作符被用作进入任一属性,或数据属性或方法
3、OOP的力量
3.1、捆绑对象分享通用的属性以及对这些属性的操作
3.2、使用抽象来区分如何实施对象和如何使用对象
3.3、建立对象抽象的层级来从其他类对象中继承行为
3.4、在Python基础类的顶层创造我们自己的对象类型
4、完成ps0的1-3

1
2
3
input("Enter number x: ")
input("Enter number y: ")
print("x**y= ",x**y)

5.学习使用Typora,早就下载了软件,但一直不会使用,打卡一直用的page文档,今天尝试使用。

第18天:20190712

学习时间:2小时
学习内容:MIT Lecture 9前半部分+PPT(1-15)+ps0
学习收获:
上节课通过坐标和分数两个例子掌握通过类实现的抽象数据类型,本节课继续深入了解类和继承的概念。
1、实现类与使用类是从两个不同的角度来编写代码:

  • 实现类要定义类(一个新的对象类型)、定义数据属性(对象是什么)、定义方法(如何使用对象)
  • 使用类则是创建对象类型的实例,对它们进行操作。

2、对象类型的类定义与类实例的区别:

  • 类的名字是类型;类定义属性,self是参数;类定义数据和方法,适用于所有的实例
  • 实例是一个专门的对象;数据属性的值在不同的实例中是不同的;实例具有类的结构

3、使用OOP和类能够模拟真实世界,将具有相同属性的对象归类处理,使同类对象具有数据属性(是什么)和程序属性(可以干什么)
4、如何定义一个类:

1
2
3
4
class Animal (object):
def __init__(self, age):
self.age = age
self.name = None

5、getters和setters方法被用于类的外部读取数据属性。

1
2
3
4
5
6
7
8
class Animal (object):
def __init__(self, age):
self.age = age
self.name = None
def get_age(self):
return self.age
def set_age(self, newage):
self.age = newage

6、点计法示例及注意事项:
a = Animal(3)
a.age #点计方法
a.get_age() #getters方法
对于一个对象实例a,用a.age可以进入数据属性,允许但不推荐;用a.get_age()是更好的进入方法。
7、层级:

  • 父类(超类)
  • 子类(亚类):继承父类所有的数据和行为;增加更多信息;增加更多行为;覆盖行为

8、ps0:

1
2
3
4
5
6
7
import math    
input("Enter number x: ")
input("Enter number y: ")
x = 2
y = 3
print("x**y = ",x**y)
print("log(x) = ",int(math.log(x,2)))
第19天:20190715

学习时间:2小时
学习内容:MIT Lecture 9后半部分+PPT(16-26)
学习收获:
1、以一系列具体的代码实例来帮助理解父类和子类的继承方法,这一部分视频内容要将代码实例拷贝到spyder中去运行一遍才好理解。
2、子类继承父类的所有属性,还可以经由method添加新功能,子类可以调用添加的新功能,父类调用则会报错;子类中可以没有init,直接使用父类中的版本。
3、使用哪一个方法?

  • 子类可以有和父类相同的方法名
  • 对于一个类的实例,在当前类定义中寻找方法名
  • 如果找不到,到上一层级中去找方法名(比如父类、祖父类等)
  • 使用你向上一层级找到的第一个具有那个方法名的方法

4、类变量:类变量和它们的值在所有的类实例中被分享,用tag标签表示在def init之前。
5、面向对象编程(OOP)的特点:

  • 创造你自己的数据收集
  • 组织信息
  • 分解工作
  • 用一致的方式进入信息
  • 添加复杂的层级
  • 像函数一样,类是一种用于编程的分解和抽象的实现技巧

第20天:20190716
学习时间:2小时
学习内容:MIT Lecture 10 + PPT(1-20)
学习收获:
1、对程序的效率有初步认识,理解如何测量算法的增长、大O表示法、复杂性类。
2、程序可以有不同的实现方法,哪一种选择更高效,将程序运行的时间效率(运行快慢)和空间效率(运行时占用内存的大小)分开考虑,在二者之间获取最佳平衡方案。
3、如何评估程序的效率?

  • 用计时器
  • 计算操作步骤
  • 应用量级这个抽象概念(最合适的评估方式),它能实现:
    • 当输入非常大时想要评估程序的效率
    • 当输入规模增长时想要表达程序的运行时间增长
    • 想要尽可能简洁的设置增长上限
    • 不需要精确到准确的增长,是增长的级别
    • 我们将考虑在运行时间方面的最大因素(程序的哪一部分将花最长运行时间?)
    • 因此,通常我们想要在最糟糕情况下,根据输入的函数规模,找到尽可能简洁的增长上限

4、测量量级用大O表示法:

  • 大O表示法测量一种渐进增长的上限,通常叫作量级
  • 大O或O()被用于描述最差情况
    • 最差情况通常是程序运行的瓶颈
    • 表达与输入规模相关的程序增长率
    • 评估算法而非机器或执行

5、量级的类型:常数、线性、二次方、对数、对数线性、指数
6、对课程的学习基本是通过努力理解并翻译PPT来完成的,很吃力,但知道自己在进步,加油!