NCF参数化建筑论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 262714|回复: 154
打印 上一主题 下一主题

[个人作品] 面向设计师的Python基础教程 --- 第三课 Python 基础语法规则 & 条件控制

  [复制链接]
跳转到指定楼层
1m
发表于 2013-9-3 21:32:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 wdc63 于 2013-9-11 01:01 编辑

第二课传送门
NCF显示不好,要获得更好的阅读体验,请访问我的博客:www.alwayswdc.com,但请在NCF进行回复讨论
第三课 Python 基础语法规则 & 条件控制


一 Python基础语法规则

基础语法规则前面已经悉数介绍了一些,这里我们来做一个总结,当然也包含一些前面没有讲到的部分。

1 注释规则
你已经知道了,注释是用于对源代码的解释,再好的编程语言如Python这种可读性极强的语言都是需要在代码内作注释的,注释部分的内容在程序运行时会忽略。Python中注释有两种方法,一种是使用#进行一行注释,另一种是使用""" """的多行注释。后一种注释一般会用在某个代码文件的开头,用来解释整个代码文件所包含的大致内容。在上节课内容接触很多了,不再举例。


2 语句分行与合行


根据PEP的代码规范,一行代码只能描述一个语句,Python中也提供了将多句代码放于一行,或者将一句较长的代码分成多行编写。
•     多行句子(必须处于同一个层级内,阅读完下面的代码缩进你就懂了)可以用;(分号)隔开放在同一行当中。(其他语言中也有类似方法,例如VB中使用冒号)
•     一句太长的句子可用 \ 反斜杠符号分解成多行。
•     用()[]{}这个几个括号扩起来的语句可以跨行

a = 1 ; b = 2 ; c\
=3
a = [3,
     4,
     5]
if (a == b and
    c == d)

尽管这个方法存在,前者一般不推荐,后者实在句子太长不得已才使用,因为这种方法是不利于代码理解的。有些程序员就是喜欢搞怪,专写混乱的代码,例如下面这个例子,是一个完全可以运行的代码。结果生成一个拼花图案。这样的代码你能读懂么?

                               
登录/注册后可看大图

_                                 =\
                                """if!
                              1:"e,V=100
                            0,(0j-1)**-.2;
                           v,S=.5/  V.real,
                         [(0,0,4      *e,4*e*
                       V)];w=1          -v"def!
                      E(T,A,              B,C):P
                  ,Q,R=B*w+                A*v,B*w+C
            *v,A*w+B*v;retur           n[(1,Q,C,A),(1,P
   ,Q,B),(0,Q,P,A)]*T+[(0,C             ,R,B),(1,R,C,A)]*(1-T)"f
or!i!in!_[:11]:S      =sum([E          (*x)for       !x!in!S],[])"imp
  ort!cair               o!as!O;      s=O.Ima                geSurfac
   e(1,e,e)               ;c=O.Con  text(s);                M,L,G=c.
     move_to                ,c.line_to,c.s                  et_sour
       ce_rgb                a"def!z(f,a)                   :f(-a.
        imag,a.       real-e-e)"for!T,A,B,C!in[i       !for!i!
          in!S!if!i[""";exec(reduce(lambda x,i:x.replace(chr
           (i),"\n "[34-i:]),   range(   35),_+"""0]]:z(M,A
             );z(L,B);z           (L,C);            c.close_pa
             th()"G               (.4,.3                 ,1);c.
             paint(               );G(.7                 ,.7,1)
             ;c.fil               l()"fo                 r!i!in
             !range               (9):"!                 g=1-i/
             8;d=i/          4*g;G(d,d,d,              1-g*.8
             )"!def     !y(f,a):z(f,a+(1+2j)*(       1j**(i
             /2.))*g)"!for!T,A,B,C!in!S:y(M,C);y(L,A);y(M
             ,A);y(L,B)"!c.st              roke()"s.write_t
             o_png('pen                             rose.png')
             """                                               ))


3 缩进与代码组
像if、while、def、for这类的由多行语句组成的复合语句可以视为一个代码组,使用缩进来分割不同的代码组是Python中最为喜爱它的程序员津津乐道的特点,大部分其他语言一个代码组使用符号来与其他代码组区分,例如C、JAVA的结尾往往会有n多个括号看得你脑壳大。如下面的例子,二分法算法中的一个代码组,上面的是JAVA代码,下面的是Python代码,Python去除了传统编程语言中的许多符号,例如这里JAVA有的括号,结束符号分号,使用缩进的方式来分割代码组。

     if (num > nums[center]) {
      start = center + 1;
     }
     if (num < nums[center]) {
      end = center - 1;
     }
     center = (start + end) / 2;
    }
   }
   return -1;
}
}


================================================================
if num > nums[center]:
    start = center + 1
if num < nums[center]:
    end = center - 1
center = (start + end) / 2
return - 1

缩进空格数没有硬性规定,但二级代码组必须在其父级代码组的基础上再缩进。在Python中一般使用4个空格表示每级缩进较好,也可以用tab键来控制缩进,但个人不推荐,这容易引起代码的混乱,这也是PEP代码规范中的要求。Python的缩进组织代码方式,不但代码风格优雅,而且大大提高了代码的可读性,还可以保护你的键盘。
另外,Python在复合句或简单句的结尾不需要终止符号,例如JAVA中的分号。缩进结束则代表代码组的结束。

4 字符集
Python源代码中的使用的字符集范围是有限制的,有些同学的键盘上带有各种稀奇古怪的可爱字符键,或者输入法中带有许多可爱字符,但是要注意,在Python中,除了字符串内容和注释内容之外的所有字符,必须符合ASCII的128个字符代码。而且最好在源代码的起始一行进行以下声明:
#-*- coding:utf-8 -*-
或者iso-8859-1等常用编码,但仅能声明一个,即使这样做,你也只能输入该编码支持的字符集,例如搜狗输入法能输入的❤★℃,utf-8编码支持而iso-8859-1不支持。

5 保留关键字
Python有一个关键字字典,字典内的单词是不能用来作为任何变量名的,包括函数、类和一般变量名,但注意Python中严格区分大小写,如果你将某个关键字的首字符大小写改变了则可以使用,虽然不推荐这样,关键字字典请参见上一课内容。

>>> with = 1
SyntaxError: invalid syntax
>>> With = 1
>>>




二 条件控制
1 程序执行的三种基本结构
对于一门当代的计算机语言,不论多么复杂的代码在执行时,它无非遵循三种结构:
•     第一种:顺序执行,对于代码而言,从前一句往下一句执行即是一种顺序执行,这种执行方式是所有编程语言都遵循的规则,除非特殊控制,不会有哪种编程语言先执行第二句再执行第一句。曾经许多较老的程序语言例如BASIC都有GOTO语句,以指定程序跳到指定的某行,这种方法导致代码杂乱无章,被现代语言不一而同的摒弃了,遵循程序的三种基本结构完全可以写出任何代码。
•     第二种:条件执行,后续处理需要根据特定的情况选择不同的分支执行,就如同你的人生,在某个拐点你做出了不同的选择,人生将沿着不同的轨迹进行下去。(不过程序是可以一遍一遍重来的,无需担心条件分支写错了会对你的人生造成影响^_^)。
•     第三种:循环执行,程序反复执行某些步骤或操作,永远执行(死循环)或当执行的条件满足某个特定要求时即终止循环。

本课我们来学习条件执行的相关问题。很多人会觉得很简单,不就是if-else么,不过Python中与条件执行相关的内容深入下去还是比较复杂的,而且许多问题如果忽视将在后续的学习当中带来麻烦。

2 程序流程图
我们在做建筑设计时必须要绘制草图,一来就上计算机的学生老师会说你不是好学生,如果某个程序员在进行某个较为复杂的程序编写时,一上来就直接开工撰写代码,这家伙不然就是天才,不然就不是好程序员。
程序流程图就是在程序编写之前对程序结构进行规划的一种图形描述,根据程序规划的规模程度也有"总规","控规"之分。建议各位以后在程序编写前养成画流程图的习惯,帮助你在编写程序时拥有清晰的思路,许多程序员的经验表明流程图比伪代码要有效得多。对于一个有经验的程序员来说,在代码规范熟悉以后,完成一个程序的结构设计也就完成了一半工作,剩下的便是让代码运行便是。
流程图的画法非常简单,以下几个图形是最为常用的图形符号,大部分时候在纸上画即可,最好遵循以下这种通用的符号,如果需要用到论文等处,建议用SmartDraw 2012来绘制程序流程图。

                               
登录/注册后可看大图

                               
登录/注册后可看大图
3 Python条件控制
条件控制在许多编程教材上也使用分支结构等词汇,是同一个道理。Python中进行条件控制的语句不像C语言可用if-else,也可以用switch-case那么复杂,单纯的只有if-elif-else构成的语句,根据条件判断的复杂性else和elif是可选的,另外程序异常条件处理try-except,和从运算符运算扩展而来的三元运算符也属于条件控制范畴,这里一并讲解。

3.1 if-elif-else语句
根据条件控制的不同,if可以单独使用形成单选条件结构,也可以与else或elif配合使用形成双选条件结构或多选条件结构。下面结合程序流程图分别来看

3.1.1 if构成的单选条件结构
if单独使用构成的条件结构叫单选条件结构,如果if之后的表达式为真,则进行if代码组内的语句,然后进行下一步,如果if之后的表达式为假,则跳过if代码组内的语句,直接进行下一步,其语法形式如下:

if 判断表达式:
    语句体

注意上式中if和判断表达式用空格隔开,其后跟上冒号(:),if代码组内的语句体相对于if进行缩进。if语句的流程图如下:

                               
登录/注册后可看大图
注意if后的表达式必须是一个判断表达式,不能是一个变量赋值或其他语句,这个判断表达式可以是一个复合判断表达式,但返回值必须是真或假其中之一,例如我们输入一个整数判断它是否是3的倍数,如果该数是3的倍数,则在屏幕打印出来,不是则什么都不做,这里我们要接触到一个新的内置函数:input(),代码如下:(2_if.py)

##input函数为让用户输入一个值,这个值默认当做字符串处理,若要用作其他类型,需进行转换
num = input('请输入一个整数:')
##if后的语句为将num转换为整数之后再对3取余数
if int(num)%3 == 0:
    print(num,'是3的倍数')
>>> ================================ RESTART================================
>>>
请输入一个整数:56
>>> ================================ RESTART================================
>>>
请输入一个整数:33
33 是3的倍数

这里接触到的input()函数Python3.x和Python2.x含义是不同的,Python2.x中有input()和raw_input()两种方法,前者会对输入的类型进行自动判断,后者强制输入类型为字符串,但在Python3.x中取消了raw_input()这种方法,只有input(),且输入的数值类型默认为字符串,我们需要使用int()函数将其转换为整数。
当然,用户往往是不老实的,你让他输入一个整数,他偏偏要输入字母或者小数,因此在处理用户输入时要进行异常判断,若用户输入不是需要的类型,则要提醒他,后面的部分我们就会讲这类异常条件处理。

3.1.2 if-else构成的双选条件结构
if-else构成的选择结构叫做双选条件结构,如果if后的判断表达式为真,则进行if之后的语句体,如果为假则进行else之后的语句体,其语法形式如下:

if 判断表达式:
    语句体1
else
    语句体2

注意else其后也要跟上冒号(:),if-else语句的流程图如下:

                               
登录/注册后可看大图
例如我们写一个程序来判断建筑是否为超高层建筑,由于中国建筑有低层、多层和超高层之分且与类型有关,使用双选条件结构无法完成,后续的例子我们会逐渐扩展这个例子:

num = input('请建筑的高度(米):')
if int(num) >= 100:
    print('建筑高度为',num,'米,是超高层建筑')
else:
    print(('建筑高度为',num,'米,不是是超高层建筑'))


>>> ================================ RESTART================================
>>>
请建筑的高度(米):99.9
建筑高度为 99.9 米,不是是超高层建筑
>>> ================================ RESTART================================
>>>
请建筑的高度(米):100
建筑高度为 100 米,是超高层建筑


3.1.3 if-elif-else构成的多选条件结构
如果一个判断有三个或以上的条件,最好用到多选条件结构,当然也可以将条件分成两个部分,然后每个部分再细分,用嵌套的双选条件结构也可以完成,不过后者的结构要复杂一些效率也更低,编程时最好使用表达最明确,效率最高的方法。
if-elif-else构成的多选条件结构将从上往下依次匹配条件是否满足,若在某一步满足,将跳过后面的所有部分,其语法形式如下:

if 判断表达式1:
    语句体1
elif 判断表达式2:
    语句体2
    ....
elif 判断表达式m:
    语句体m
else
    语句体n



注意,最后一个else也可以没有,这样当前面所有条件都不满足时,程序什么也不做直接跳过。最后一个else是不加任何条件的,它是处理所有前面条件都不匹配时的情况,所有else必须放在最后,不能放在中间。其流程图如下:

                               
登录/注册后可看大图
有了多选条件结构我们就来进行稍微复杂点的例子了,并且用到嵌套条件判断的,首先在一个双选条件内将建筑分为住宅和公共两种情况,然后再分别进行低层、多层、高层和超高层的判断。代码如下:(4_if-elif-else.py)

print ('1 住宅类建筑','2 公共类建筑' )
kind = input('请选择民用建筑的类型:')
if int(kind)==1:
    floors = int(input('请输入住宅建筑的层数:'))
    height = float(input('请输入住宅建筑的高度:'))
    if floors <= 3 and height < 100:
        print('住宅建筑层数为:',floors,',为低层住宅。')
    elif floors > 3 and floors <= 6 and height < 100:
        print('住宅建筑层数为:',floors,',为多层住宅。')
    elif floors > 6 and floors <= 9 and height < 100:
        print('住宅建筑层数为:',floors,',为中高层住宅。')
    elif floors >= 10 and height < 100:
        print('住宅建筑层数为:',floors,',为高层住宅。')
    else:
        print('住宅高度超过100m,''为超高层建筑。')
if int(kind)==2:
    floors = int(input('请输入公共建筑的层数:'))
    height = float(input('请输入公共建筑的高度:'))
    if height < 24 and floors!=1:
        print('公共建筑高度为:',height,',为多层建筑。')
    elif height >= 24 and floors!=1:
        print('公共建筑高度为:',height,',为高层建筑。')
    elif height <100 and floors==1:
        print('公共建筑只有1层且小于100米'',为单层建筑。')
    elif height >=100:
        print('公共建筑高度为:',height,',为超高层建筑。')


>>> ================================ RESTART================================
>>>
1 住宅类建筑 2 公共类建筑
请选择民用建筑的类型:1
请输入住宅建筑的层数:33
请输入住宅建筑的高度:99
住宅建筑层数为: 33 ,为高层住宅。
>>> ================================ RESTART================================
>>>
1 住宅类建筑 2 公共类建筑
请选择民用建筑的类型:2
请输入公共建筑的层数:150
请输入公共建筑的高度:887
公共建筑高度为: 887.0 米,为超高层建筑。


3.2 异常条件处理
很多时候我们编程过程中捕获的条件不能确定是否满足我们需要,也就是说它有可能造成程序异常,出现错误,例如我们让用户输入一个数字,用户却输入了字母,如果强行进行下一步的数字运算,程序就会抛出错误。在Python中,我们可以使用Try-except-else语句来处理程序异常事件,Try之后跟一句你无法判断语法是否成立的语句,如果不成立,根据错误类型执行except中的语句,如果成立,分两种情况,else存在的话就执行else之后的语句,else不存在的话就跳过整个代码组。从程序结构的角度来讲,这也是一种条件执行控制。try-except-else构成的语法形式如下:

try
    语句1
except 错误名字1:
    语句体1
    ....
except错误名字2:
    语句体m
else
    语句体n



以上语法中,except也可以不跟错误名字,这样的话except只能存在一个,所有错误类型都会执行except后面的语句。
例如前面里例子,我们无法判断用户输入的是否是一个整数,需要用try语句来对用户的输入做出评判,第二课有讲到,Python中的位运算对于单个变量来说,只支持整数,我们可以用此来判断用户是否输入的是整数,如果不是整数就将返回用户一行错误提示。代码如下:(5_try.py)

num = input('请输入一个整数:')
try:
    ~eval(num) ##eval()函数用于将可以转换为整数或浮点数的字符串转换之,~为按位异或运算
except:
    print('请输入整数,而不是其他类型的数字')
    exit() ##exit()函数用于退出程序
if int(num)%3 == 0:
    print(num,'是3的倍数')


>>> ================================ RESTART================================
>>>
请输入一个整数:'abc'
请输入整数,而不是其他类型的数字
>>>
请输入一个整数:2.0
请输入整数,而不是其他类型的数字
>>>
请输入一个整数:6
6 是3的倍数

以上算法中我们又学到两个新的函数eval()和exit(),都非常常用,注意看注释,用help()命令取得帮助。当然最好的算法是在出现错误之后让用户有机会输入第二次,不过这必须用到循环的知识。而且如果有这样一段程序能够反复使用,那更好,我无需在每一次用户输入时都使用try-except来进行判断,这涉及到后面的函数知识,不过这里我先放出这样的代码,并且建议使用Rhino.python的同学,如果你的代码是要给其他人运行的,请确保每一个输入都进行类型检查,这是程序友好的必要条件。
以下我们制定一段函数,用于前面判断建筑高度类型的程序中用户输入类型的检查,制定函数用def关键字,让输入的参数直接调用这个函数进行错误检查,如果出现类型错误,让用户再次输入,并友好的提供用户不能理解时程序中断的机制。关于函数和循环的知识属于后面的内容,这里不能理解也没有关系。代码如下,函数用法详见源代码中的注释:(6_try2.py)

def getinput(parm,kind1,kind2,errmessage):
    while 1:
        try:
            eval(parm)
            if isinstance(eval(parm),kind1) orisinstance(eval(parm),kind2):
                return eval(parm)
            else:
                newparm = (input(errmessage))
                if newparm == 'exit':
                    exit()
                parm = newparm
        except:
            newparm = (input(errmessage))
            if newparm == 'exit':
                exit()
            parm = newparm
print ('1 住宅类建筑','2 公共类建筑' )
kind = getinput(input('请输入建筑类型:'),int,None,'请确保输入一个整数,如果您无法理解,请输入"exit"退出程序:')
if int(kind)==1:
    floors = getinput(input('请输入住宅建筑的层数:'),int,None,'请确保输入一个整数,如果您无法理解,请输入"exit"退出程序:')
    height = getinput(input('请输入住宅建筑的高度:'),int,float,'请确保输入一个有理数,如果您无法理解,请输入"exit"退出程序:')
    if floors <= 3 and height < 100:
        print('住宅建筑层数为:',floors,',为低层住宅。')
    elif floors > 3 and floors <= 6 and height < 100:
        print('住宅建筑层数为:',floors,',为多层住宅。')
    elif floors > 6 and floors <= 9 and height < 100:
        print('住宅建筑层数为:',floors,',为中高层住宅。')
    elif floors >= 10 and height < 100:
        print('住宅建筑层数为:',floors,',为高层住宅。')
    else:
        print('住宅高度超过100m,''为超高层建筑。')
if int(kind)==2:
    floors = getinput(input('请输入公共建筑的层数:'),int,None,'请确保输入一个整数,如果您无法理解,请输入"exit"退出程序:')
    height = getinput(input('请输入公共建筑的高度:'),int,float,'请确保输入一个有理数,如果您无法理解,请输入"exit"退出程序:')
    if height < 24 and floors!=1:
        print('公共建筑高度为:',height,'米,为多层建筑。')
    elif height >= 24 and height <100 and floors!=1:
        print('公共建筑高度为:',height,'米,为高层建筑。')
    elif height <100 and floors==1:
        print('公共建筑只有1层且小于100米''米,为单层建筑。')
    elif height >=100:
        print('公共建筑高度为:',height,'米,为超高层建筑。')


>>> ================================ RESTART================================
>>>
1 住宅类建筑 2 公共类建筑
请输入建筑类型:1
请输入住宅建筑的层数:3.2
请确保输入一个整数,如果您无法理解,请输入"exit"退出程序:5.0
请确保输入一个整数,如果您无法理解,请输入"exit"退出程序:'sfg'
请确保输入一个整数,如果您无法理解,请输入"exit"退出程序:6
请输入住宅建筑的高度:18.5
住宅建筑层数为: 6 ,为多层住宅。


3.3 三元运算符
在C、JAVA等语言中,C?X:Y问号和冒号组成的三元运算符(C为判断,正确执行X,错误执行Y)可以看做条件控制的简写,在编辑代码时让代码更为简洁,Python中官方的解释文档中并没有这样的三元运算符,不过可以用and or组成的语句来代替,三元运算符的原理可以参加第二课中的最后一段代码有讲解。注意Python中的三元运算符有一种例外,详见以下代码(7_sanyuan.py):

a = 1
b = 2
##如果and和or之间为一个false值或空值,将永远执行or后面的表达式
print(a>b and a or b)
print(a<b and a or b)
print(a>b and 0 or b)
print(a<b and 0 or b)
print(a>b and '' or a)
print(a<b and '' or a)


>>> ================================ RESTART================================
>>>
2
1
2
2
1
1

游客,如果您要查看本帖隐藏内容请回复
本课练习:1 练习一些复杂的布尔运算,
                       2 设想一个场景游戏,例如你进入一个陌生的房子,然后眼前几种食物,用户通过不同选择会进行不同的方向,用判断控制来完成,我以前经常这样干


完成的作业有疑问的可以发到i@alwayswdc.com,我会尽量帮助您。

评分

参与人数 2强度 +2 照度 +3 收起 理由
奇奇狗 + 1 感谢分享!
~祥~ + 1 + 3 感谢分享!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏18 分享分享
2m
发表于 2013-9-3 21:52:09 | 只看该作者
第一个踩一下。。支持中。。
3m
发表于 2013-9-3 22:40:29 | 只看该作者
继续跟进,加油学习
4m
发表于 2013-9-3 23:03:10 | 只看该作者
到第三课了 大川辛苦啊~~
5m
发表于 2013-9-4 00:53:14 | 只看该作者
啥也不说了,,,,,,哇哇地
6m
发表于 2013-9-4 01:09:55 | 只看该作者
第三课了 感谢LZ!!!!
7m
发表于 2013-9-4 03:49:24 | 只看该作者
支持中      
8m
发表于 2013-9-4 08:56:40 | 只看该作者
很给力啊,第三课出来了
9m
发表于 2013-9-4 09:34:49 | 只看该作者
继续学习。。。。。。中
10m
发表于 2013-9-4 09:40:34 | 只看该作者
学习ing~~~~
11m
发表于 2013-9-4 09:50:27 | 只看该作者
川哥犀利 学习一下看看
12m
发表于 2013-9-4 09:58:29 | 只看该作者
版主十分给力
13m
发表于 2013-9-4 10:23:36 | 只看该作者
aha,休假在家养病,瞄到川哥的py教程又更新了,垂死病重惊坐起的赶脚有木有?
14m
发表于 2013-9-4 10:58:28 | 只看该作者
3q for sharing
15m
发表于 2013-9-4 11:51:07 | 只看该作者
以后要印成书出版呀!!
16m
发表于 2013-9-4 13:02:19 | 只看该作者
lookinging!!
17m
发表于 2013-9-4 13:03:18 | 只看该作者
还有隐藏?!!
18m
发表于 2013-9-4 14:01:47 | 只看该作者
好东西 顶啊啊啊啊
19m
发表于 2013-9-4 15:29:29 | 只看该作者
支持一下,
20m
发表于 2013-9-4 15:48:28 | 只看该作者
要顶。。。

小黑屋|手机版|NCF参数化建筑论坛 ( 浙ICP备2020044100号-2 )    辽公网安备21021102000973号

GMT+8, 2024-11-22 01:53 , Processed in 0.085767 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表