www.codesculptor.org
1以游戏的思路来理解编程,就是一系列的规则,能够形成封装的函数,实现一定的输入和输出构建对应关系。实际上,游戏就是这个复杂的函数,能够针对玩家的输入有一定的输出(如得分,游戏结束等等)。幸运的是,我们不必从头做起,我们可以利用前人写的各种工具库来快速实现。
2项目思维,将复杂的目标分解为一个个小的模块,乃至函数(以文件的形式)。于是可以最后能够开发各种游戏乃至软件。以python面向对象的编程的特点,我们需要定义一个个的类和函数,理论上各种变量就对应于现实的一个属性,只要描述的属性足够多,可以以更高的精度来逼近现实事物。面向对象,基于类和对象,就是属性+方法,属性就是定义的不同变量(描述不同性质),方法就是各种定义的函数。本质上对象是对现实的一种抽象,而对象是实例的一种抽象,实例是对象的具体表达。如我们都住在房子(对象),但具体的位置,大小等等(实例)是不同的。简单的小项目不需要模板,但实现复杂的功能,有模板能够更好地完成工作
3程序需要在一定的运行环境实现其功能。程序本质上都是基于文本符号的交互,更底层的是各种逻辑门的运算,我们通过各种定义如ASCII码来构建符号与二进制数字的关系,于是能够通过文本的输入与计算机进行交互。如今的图形界面的交互也是这样的思路。于是我们能够通过这些措施来实现高于语言的功能,如我们的各种APP。
4表达式的形成就是简单的符号组合(基本的算术运算符有加、减、乘、除、乘方),而运算符号有一定的优先级。然后在这个基础可以形成函数,而变量这些功能就对应于数学的定义域,函数的输出就对应于值域。这些基本的数据类型如整数型int,浮点数型float,字符串型string等等就是这些变量的类型。所谓的强制类型转换就是改变其存储数据的应用范围,如整数转化为浮点数是精度的改变(任何超出15位小数精度的部分都会被丢弃)
5变量命名是重要的(在Python中有效的变量名由字母、数字和下划线组成,变量名必须以字母或下划线开头,变量名是要区分大小写的),一方面这是储存数据的单元(用于存储“值”的占位符),另一方面作为函数的参数需要比较明确的意义以便于人们理解。实际上,把值存入变量可以避免一次又一次的计算同一个表达式,在我们的数学计算是有意义的。变量名要能够帮助理解变量所代表的值的含义。然后变量需要赋值,一般来说初始化是好习惯,然后再更新即放入一定的表达式中运算,最后实现一定的输出。当然,我们需要养成测试的好习惯,即在运行程序前就思考正确的答案应该是什么,从而为代码的修改提供依据(使用print语句)。还有,及时保存程序很重要,时刻记住ctrl+s。
6简单的程序是一行一行输入语句,运行程序后语句立刻执行,这是基本的措施,但很繁琐,我们需要进一步抽象。这就是函数,能够如同变量的值减少重复运算,这种架构其实也是代码,但只有当你调用这个函数,才会执行函数内部的代码。一次性定义一段代码之后可以多次调用它,这无疑大大简化各种计算。将函数的用处清楚地写入注释里,这有助于把一整套函数集成起来。函数头:def函数名(参数):;函数体:具体的语句如计算公式,然后有一定的输出或者return。函数只有被调用时才执行。实际上函数可以被视为黑箱,我们知道其可以针对一定的输入实现一定的输出,这最后能够升维到算法的层次甚至各种功能。
7代码如何运行,结合冯诺依曼计算机体系,我们知道这是存储器的不同区块的数据的选择性提取到CPU计算(以变量为基础,其存储于硬盘的一定地址),然后各种返回值也同样存储于特定的存储器地址中。
8模运算mod,就是被除数剩下的余数,a=b*c+d,amodc=d.可以用于计算12小时制或24小时制的小时,如20:00时再过8个小时是几点的问题,可以用20加8得28,可以取24的余数得4。使用模运算和余数可以来做24小时时钟的小时计算。这是计算周期的一个很重要的方法,如2D游戏对象可以到处移动,当一个物体移动到界面边缘的情况,有时希望它可以环绕屏幕运动,在一侧消失然后在另一侧冒出来。其位置的数值在这个情况的变化可以使用模运算,新位置值等于原来的位置值加上移动值然后取得屏幕宽度的余数。
如何处理字符串和数字,即数据类型的强制转换,如数值转换为字符串输出,可以使用str函数将数字转换为字符串,从而能够使用不同的运算(数字的+是计算,字符串的+是连接字符串)
调用Python的一些内置函数是设置好的,Python以外的函数集即模块,是其他人建立好并添加到Python中的,要想调用这些函数需要将其导入如importsimplegui。
9计算机的本质是逻辑运算。任何复杂的程序可以分解为基本的布尔逻辑包括非(NOT)、与(AND)和或(OR)。这些基本的逻辑门的不断组合嵌套能够形成复杂的函数。
10程序的控制流程,从基础的顺序执行到顺序分支循环语句的结合(可以根据程序中的值来改变控制流程),再到各种复杂的叠套结构。在Python中根据数据来改变控制流程的方式是使用if语句,可以有多个条件通过与或非连接起来。使用任意的布尔逻辑和断言的能力允许行事强大而灵活。在查验一个函数的断言时函数名要以is开头。
11测试和调试debug。得到一个错误信息,要去理解它并解决问题,这需要学习一些检测的技巧。如当我们写错函数名或变量名就会得到一条名称错误信息,因为它们没有被定义。拼错了在句号之后的部分都会得到一个属性错误。每一个函数头,“if“和“else“都以冒号结尾。注意全局变量和局部变量的区别。
编码风格和可读性:良好的命名(变量有意义)并确保命名一致,将相关信息放进文档字符串,清晰的注释。用多种途径简化条件和其他内容,产生更容易理解的代码。在定义之间加空行,在表达式之间加入空格,更具可读性。
12程序的控制流程取决于程序结构以及具体输入,这是面向过程的方法。而由事件驱动的编程模型,可用来构建交互式应用。不同的程序块等待不同的输入作为响应条件,然后运行处理程序的函数,处理程序运行完成后函数块继续等待。于是这些函数的处理的组合数是指数级爆炸增长的,从而可以灵活地处理各种情况。这和顺序分支循环语句的组合思想是一致的。最后用某种事件来触发程序的退出,即停机。
13事件有很多种,它们取决于你运行系统的类型和你的兴趣所在:输入事件(按钮或文本框输入),键盘事件(按键按下事件或按键抬起事件),鼠标事件(点击事件或拖动事件)和计时器事件(周期性触发)。对于一个事件,要写个处理程序,但不会给所有同一事件都写同一个处理程序。系统的大部分时间都在等待事件发生。有一个计时器事件的周期性触发,避免等待用户的动作。我们使用计时器来触发,然后我们再设计触发的操作。
事件队列:事件一发生系统就会把它们放到队列里。程序在等待时,系统会查看事件队列,然后运行直到事件队列是空为止。写出的程序应该能响应事件做出相应的操作,不管它们发生的顺序如何。处理程序正在运行时是独占的,如果有新事件,它们仅仅被排进内部的事件队列(而不触发相应的处理程序),因而如果有个死循环在里面,就阻断了所有其他事件的处理。
14编程模型:先编写处理函数--注册这些函数--响应事件并被执行--程序结束。当系统在运行时,程序大多数时间都在等待,当事件发生时,它首先被放进事件队列中,然后系统从事件队列中依次抽取一个,并运行相应的处理程序。程序员不能决定函数什么时候被调用和发送,而是事件发生时系统调用处理函数。我们只知道如果事件发生,特定的处理函数就会运行。这是图形用户界面编写的底层思维,即事件驱动编程,事件处理程序对事件作出回应。
15在事件驱动的程序里,不同的处理程序需要共用一组信息来令交互式程序得以运行:让所有处理函数一起工作,即让它们共享一组全局变量。
全局变量(在函数外部定义变量,在函数内部修改全局变量是不可能的,除非声明该变量是全局变量global;使用全局变量实现各种处理函数之间的数据通讯是最简便的方法,也可以隐藏信息,控制信息可见度)和局部变量(在函数内部创建的变量,只能在该函数内部修改和使用,函数调用结束之后局部变量也就不复存在了。应该优先使用局部变量)
16SimpleGUI程序结构:1定义全局变量,这基本上是程序的状态;2定义程序所需的任意辅助函数,用来帮助事件处理函数完成特定的任务;3定义程序需要用到的类;4定义事件处理函数,可以使用你在程序中定义的全局变量,辅助函数和定义好的类;5创建Frame;6注册所有我们需要的事件处理函数7启动Frame和程序中的定时器。
17交互式应用程序(如同类的定义,需要有基本的属性(存储数据的变量)和操作):首先需要搭建一定的框架,然后确定相应的控制区(创建按钮,输入框等等),迭代式开发,不断添加需要的功能,最后形成有一定功能的整体。
18计算机是如何工作的以及它们是如何组织绘图过程的:显示器根据电脑所作的显示某种视觉输出,分辨率对应到二维的像素网格,按逻辑存储在帧缓存的地方(跟踪你在屏幕上看到的像素的值的数据结构);电脑是如何实际地让这些东西移动:它快速地把帧缓存扫一遍并且重新绘制其内容。刷新率表示了计算机把帧缓存的内容显示在实际屏幕上的频率。每个应用或屏幕要给自己注册一个绘画处理程序的特殊函数。
字符串处理,大多数情况下都是将字符串打印输出到控制台。计算机科学从零开始计数。可以写复杂的条件语句以构造适合的程序的字符串