目录
九、编程学习的两大瓶颈
1、知识学完就忘
1)用法查询笔记
代码含义往往用【#注释……】写在代码后面
实际运行效果往往用【# 》》注释……】写在代码下方
2)深度理解笔记
侧重解决“为什么要用”以及“怎么用这个知识点”的问题
3)知识管理
2、缺乏解题能力
练习:九九乘法表
用参数end控制两个print之间不换行
print('hello')
print('world')
print('hello',end=' ')
print('world')
#》》
hello
world
hello world
用print('')来控制换行
for i in range(1,10):
for j in range(1,i+1):
print('%d x %d = %d'%(j,i,j*i),end=' ')
print(' ')
十、函数
1、函数的定义
函数是组织好的,可以重复使用的,用来实现单一功能的代码。
2、定义和调用函数
#函数名:最好是取体现函数功能的名字,一般用小写字母和单下划线、数字等组合
def greet(name):
#参数:根据函数功能,括号里可以有多个参数,也可以不带参数,命名规则与函数名相同
#规范:括号是英文括号,后面的冒号不能丢
print(name+'早上好')
#函数体:函数体就是体现函数功能的语句,要缩进,一般是四个空格
return
def pika1(name):
print('我最喜爱的神奇宝贝是'+name)
pika1('皮卡丘') #调用函数,输入函数名pika()并输入参数'皮卡丘'
pika1('喷火龙') #调用函数,输入函数名pika()并输入参数'喷火龙'
3、参数的类型
位置参数:对应参数appetizer和course的位置顺序传递的
默认参数:dessert='双皮奶' ,必须放在位置参数和不定长参数的后面
不定长参数: *barbecue 可以先生成一个元组,再传入这个参数
def menu(appetizer,course,*barbeque,dessert='双皮奶'):
print('一份开胃菜:'+appetizer)
print('一份主菜:'+course)
print('一份甜品:'+dessert)
for i in barbeque:
print('一份烧烤:'+i)
menu('凉拌海带','黑椒酱烤肉拌饭','烤鸡腿','烤土豆','烤冷面','烤牛肉串')
4、return语句
1)如果不是立即要对函数返回值做操作,那么可以使用return语句保留把返回值。
2)需要多次调用函数时,可以再定义一个主函数main(),调用非主函数的返回值。
def IQ(name):
return name+'的智商和'
def reliability(name):
return name+'的可靠'
def main(IQ_name,reliability_name):
return '我的梦中情人有着'+IQ(IQ_name)+reliability(reliability_name)
print(main ('王也','七海建人'))
3)Python的函数返回值可以是多个,多个返回值的数据类型是元组tuple。
def lover(name1,name2):
EQ=name1+'的情商和'
STRENGTH=name2+'的实力'
return EQ,STRENGTH
a=lover('刘昊然','五条悟')
print('我的梦中情人有着'+a[0]+a[1])
4)没有return语句,返回None值。
5)一旦函数内部遇到return语句,就会停止执行并返回结果。
def fun():
return 'I am coding.'
return 'I am not coding.'
print(fun())
#》》
I am coding.
5、变量作用域
【局部变量】:在一个函数内定义的变量仅能在函数内部使用(局部作用域)
【全局变量】:在所有函数之外赋值的变量,可以在程序的任何位置使用(全局作用域)
x=99 #全局变量x
def num():
x=88 #局部变量x
print(x)
num()
#打印局部变量x
print(x)
#打印全局变量x
将局部变量变成全局变量:global语句
def egg():
global quantity
quantity = 108
egg()
print(quantity)
#global语句可以将局部变量声明为全局变量
def egg():
quantity = 108
egg()
print(quantity)
#会报错,不能在函数外部(全局作用域)使用函数内的局部变量
quantity = 108
def egg():
print(quantity)
egg()
#函数内的局部作用域,可以访问全局变量
练习:生成一副扑克牌
每张扑克牌的展现形式是一个元组:(花色,大小)。
def card():
num=list(range(1,11))
num.extend('JQKA')
return[(x,y) for x in ['红心','方块','黑桃','梅花'] for y in num]
print(card())
十一、debug
bug 1:粗心
常见错误:
1.漏了末尾的冒号,如if语句、循环语句、定义函数
2.缩进错误,该缩进的时候没缩进,不该缩进的时候缩进了
3.把英文符号写成中文符号
4.字符串拼接的时候,把字符串和数字拼在一起
5.没有定义变量
6. '=='和'='混用
bug 2:知识不熟练
bug 3:思路不清
解决办法:
1.用'#'暂时注释部分感觉可能有问题的代码
2.利用print()函数,展示关键步骤的操作结果
3.根据print出来的内容,一步步寻找和解决问题
bug 4:被动掉坑
被动掉坑,是指有时候你的代码逻辑上并没有错,但可能因为用户的错误操作或者是一些“例外情况”而导致程序崩溃。
为了不让一些无关痛痒的小错影响程序的后续执行,Python给我们提供了一种异常处理的机制,可以在异常出现时即时捕获,然后内部消化掉,让程序继续运行,那就是try…except…语句。
while True:
try:
age = int(input('你今年几岁了?'))
break
except ValueError:
print('你输入的不是数字!')
if age < 18:
print('不可以喝酒噢')
#(1)因为不知道用户什么时候才会输入正确,所以设置while循环来接受输入,只要用户输入不是数字就会一直循环,输入了数字就break跳出循环。
#(2)使用try……except……语句,当用户输错的时候会给予提示。
ValueError——传入无效参数
ZeroDivisionError——0不能做除数
关于Python的所有报错类型:https://www.runoob.com/python/python-exceptions.html
练习:除法计算器
print('\n欢迎使用除法计算器!\n')
while True:
try:
x = input('请你输入被除数:')
y = input('请你输入除数:')
z = float(x)/float(y)
except ZeroDivisionError:
print('0是不能做除数的!')
except ValueError:
print('除数和被除数都应该是整值或浮点数!')
else:
print(x,'/',y,'=',z)
break
#注意else的使用
十二、田忌赛马
1.0版本
功能1:修改上次人机小游戏的代码,封装并调用函数。
功能2:从角色池中为双方随机挑选出3个角色,并随机生成血量和攻击值。
一个存放6个备选角色名的列表。
random随机抽取多个元素:
import random #先调用模块 random.sample(seq, n) #写法是random.sample() #需要传递两个参数,第一个参数是一个序列(列表、字符串、元组),第二个参数是随机选取的元素个数
属性和角色的对应——键值对应的字典,以角色名为键,以属性(血量和攻击力)为值,来存放这些数据之间的对应关系。
由于字典的键后面只能跟一个值,那血量和攻击值这两个值要如何安放呢?w1:创建两个字典分别存放;W2:利用return可以返回多个值(一个元组)的特性,将血量和攻击值的数据传递给字典里对应的键。
展示角色时,由于一方有三个角色,所以要用到循环,由于循环次数确定,我们可以用到for循环和range()函数。
import time,random
player_list = ['【狂血战士】','【森林箭手】','【光明骑士】','【独行剑客】','【格斗大师】','【枪弹专家】']
enemy_list = ['【暗黑战士】','【黑暗弩手】','【暗夜骑士】','【嗜血刀客】','【首席刺客】','【陷阱之王】']
players = random.sample(player_list,3)
enemies = random.sample(enemy_list,3)
player_info = {}
enemy_info = {}
# 随机生成两种属性
def born_role():
life = random.randint(100,180)
attack = random.randint(30,50)
return life,attack # return 多个元素时,返回一个元组(昨天课堂有讲)
# 给角色生成随机属性,并展示角色信息。
def show_role():
for i in range(3):
player_info[players[i]] = born_role()
enemy_info[enemies[i]] = born_role()
# 展示我方的3个角色
print('----------------- 角色信息 -----------------')
print('你的人物:')
for i in range(3):
print('%s 血量:%d 攻击:%d'
%(players[i],player_info[players[i]][0],player_info[players[i]][1]))
print('--------------------------------------------')
print('电脑敌人:')
# 展示敌方的3个角色
for i in range(3):
print('%s 血量:%d 攻击:%d'
%(enemies[i],enemy_info[enemies[i]][0],enemy_info[enemies[i]][1]))
print('--------------------------------------------')
show_role()
2.0版本
新增功能:分别询问玩家每个角色的出场顺序,根据玩家的排序来战斗
【排序函数的创造】简化问题:现在list1 = ['A','B','C'],通过3次input:3、2、1,将排序变为list1=['C','B','A'],并打印出来。
首先,因为输入的顺序和列表中的元素存在一个对应的关系,所以可以新建一个字典来存储,顺序为键,元素为值。然后,提取dict1的值,按键的顺序组成新的列表list1 = ['C','B','A'],用append()函数往列表添加元素。
list1 = ['A','B','C']
dict1 = {}
for i in range(3):
order = int(input('你要把'+list1[i]+'放在第几位?(请输入数字1,2,3)'))
dict1[order] = list1[i]
print(dict1)
list1 = []
# 清空原本列表list1的元素
for i in range(1,4):
list1.append(dict1[i])
print(list1)
封装到函数内后,需要考虑函数的作用域的问题,需要用global将局部变量全局化,以下是全局化前后的对比:
# 代码1
list1 = ['A','B','C']
#这里的list1 是全局变量,可以被其他函数使用
def order1():
list1 = ['C', 'B', 'A']
# orde1()里的list1是局部变量,其他函数无法使用
def use1():
print(list1)
# 这里打印的list1是最开头的全局变量
order1()
use1()
# 打印出['A','B','C']
# 代码2
list2 = ['A','B','C']
def order2():
global list2
# 将list2定义为全局变量,这样后面的函数调用时,会使用这个变量list2。
list2 = ['C', 'B', 'A']
def use2():
print(list2)
# 这里打印的list2是order2()里的list2
order2()
use2()
# 打印出['C', 'B', 'A']
类比后,游戏设计中的实现:
import random
# 将需要的数据和固定变量放在开头
player_list = ['【狂血战士】','【森林箭手】','【光明骑士】','【独行剑客】','【格斗大师】','【枪弹专家】']
enemy_list = ['【暗黑战士】','【黑暗弩手】','【暗夜骑士】','【嗜血刀客】','【首席刺客】','【陷阱之王】']
players = random.sample(player_list,3)
enemies = random.sample(enemy_list,3)
player_info = {}
enemy_info = {}
# 随机生成角色的属性
def born_role():
life = random.randint(100,180)
attack = random.randint(30,50)
return life,attack
# 生成和展示角色信息
def show_role():
for i in range(3):
player_info[players[i]] = born_role()
enemy_info[enemies[i]] = born_role()
# 展示我方的3个角色
print('----------------- 角色信息 -----------------')
print('你的人物:')
for i in range(3):
print('%s 血量:%d 攻击:%d'
%(players[i],player_info[players[i]][0],player_info[players[i]][1]))
print('--------------------------------------------')
print('电脑敌人:')
# 展示敌方的3个角色
for i in range(3):
print('%s 血量:%d 攻击:%d'
%(enemies[i],enemy_info[enemies[i]][0],enemy_info[enemies[i]][1]))
print('--------------------------------------------')
input('请按回车键继续。\n') # 为了让玩家更有控制感,可以插入类似的代码来切分游戏进程。
# 角色排序,选择出场顺序。
def order_role():
global players
order_dict = {}
for i in range(3):
order = int(input('你想将 %s 放在第几个上场?(输入数字1~3)'%(players[i])))
order_dict[order] = players[i]
players = []
for i in range(1,4):
players.append(order_dict[i])
print('\n我方角色的出场顺序是:%s、%s、%s' %(players[0],players[1],players[2]))
print('敌方角色的出场顺序是:%s、%s、%s' %(enemies[0],enemies[1],enemies[2]))
def main():
show_role()
order_role()
main()
3.0版本
功能:角色PK、打印单局战果和打印最终结果。
之前最终结果的判断是靠双方胜利局数player_victory和enemy_victory的大小比较,这里提供一种更简单的思路,设置一个变量为score = 0,玩家赢了加一分,输了扣一分,平局加零分。最终只要判断score是大于、小于或等于0就可以。
之前说过要保持函数的功能单一性,即每个功能尽量都封装成单独的函数,而pk_role()函数包含了战斗过程和战果统计两个功能。所以,可以考虑让统计单局战果的代码独立成一个函数,在pk_role()函数内部调用即可。
注意:有一些函数不会包含到主函数里,而是作为“辅助型”函数被其他函数调用,如一些返回数值的函数。如:show_role()函数内部调用born_role()函数。
import time,random
# 需要的数据和变量放在开头
player_list = ['【狂血战士】','【森林箭手】','【光明骑士】','【独行剑客】','【格斗大师】','【枪弹专家】']
enemy_list = ['【暗黑战士】','【黑暗弩手】','【暗夜骑士】','【嗜血刀客】','【首席刺客】','【陷阱之王】']
players = random.sample(player_list,3)
enemies = random.sample(enemy_list,3)
player_info = {}
enemy_info = {}
# 随机生成角色的属性
def born_role():
life = random.randint(100,180)
attack = random.randint(30,50)
return life,attack
# 生成和展示角色信息
def show_role():
for i in range(3):
player_info[players[i]] = born_role()
enemy_info[enemies[i]] = born_role()
# 展示我方的3个角色
print('----------------- 角色信息 -----------------')
print('你的人物:')
for i in range(3):
print('%s 血量:%d 攻击:%d'
%(players[i],player_info[players[i]][0],player_info[players[i]][1]))
print('--------------------------------------------')
print('电脑敌人:')
# 展示敌方的3个角色
for i in range(3):
print('%s 血量:%d 攻击:%d'
%(enemies[i],enemy_info[enemies[i]][0],enemy_info[enemies[i]][1]))
print('--------------------------------------------')
input('请按回车键继续。\n') # 为了让玩家更有控制感,可以插入类似的代码来切分游戏进程。
# 角色排序,选择出场顺序。
def order_role():
global players
order_dict = {}
for i in range(3):
order = int(input('你想将 %s 放在第几个上场?(输入数字1~3)'% players[i]))
order_dict[order] = players[i]
players = []
for i in range(1,4):
players.append(order_dict[i])
print('\n我方角色的出场顺序是:%s、%s、%s' %(players[0],players[1],players[2]))
print('敌方角色的出场顺序是:%s、%s、%s' %(enemies[0],enemies[1],enemies[2]))
# 角色PK
def pk_role():
round = 1
score = 0
for i in range(3): # 一共要打三局
player_name = players[i]
enemy_name = enemies[i]
player_life = player_info[players[i]][0]
player_attack = player_info[players[i]][1]
enemy_life = enemy_info[enemies[i]][0]
enemy_attack = enemy_info[enemies[i]][1]
# 每一局开战前展示战斗信息
print('\n----------------- 【第%d局】 -----------------' % round)
print('玩家角色:%s vs 敌方角色:%s ' %(player_name,enemy_name))
print('%s 血量:%d 攻击:%d' %(player_name,player_life,player_attack))
print('%s 血量:%d 攻击:%d' %(enemy_name,enemy_life,enemy_attack))
print('--------------------------------------------')
input('请按回车键继续。\n')
# 开始判断血量是否都大于零,然后互扣血量。
while player_life > 0 and enemy_life > 0:
enemy_life = enemy_life - player_attack
player_life = player_life - enemy_attack
print('%s发起了攻击,%s剩余血量%d' % (player_name,enemy_name,enemy_life))
print('%s发起了攻击,%s剩余血量%d' % (enemy_name,player_name,player_life))
print('--------------------------------------------')
time.sleep(1)
else: # 每局的战果展示,以及分数score和局数的变化。
# 调用show_result()函数,打印返回元组中的result。
print(show_result(player_life,enemy_life)[1])
# 调用show_result()函数,完成计分变动。
score += int(show_result(player_life,enemy_life)[0])
round += 1
input('\n点击回车,查看比赛的最终结果\n')
if score > 0:
print('【最终结果:你赢了!】\n')
elif score < 0:
print('【最终结果:你输了!】\n')
else:
print('【最终结果:平局!】\n')
# 返回单局战果和计分法所加分数。
def show_result(player_life,enemy_life): # 注意:该函数要设定参数,才能判断单局战果。
if player_life > 0 and enemy_life <= 0:
result = '\n敌人死翘翘了,你赢了!'
return 1,result # 返回元组(1,'\n敌人死翘翘了,你赢了!'),类似角色属性的传递。
elif player_life <= 0 and enemy_life > 0:
result = '\n悲催,敌人把你干掉了!'
return -1,result
else :
result = '\n哎呀,你和敌人同归于尽了!'
return 0,result
# (主函数)展开战斗流程
def main():
show_role()
order_role()
pk_role()
# 启动程序(即调用主函数)
main()
练习:石头剪刀布+index函数
要求:和电脑玩一个剪刀石头布的游戏:电脑随机出拳,我们可选择出什么。
如何简化判断猜拳赢的判断条件?
index() 函数用于找出列表中某个元素第一次出现的索引位置。
语法为:list.index(obj),obj为object(对象)的缩写。
import random
# 出拳
print('--------------来玩猜拳游戏吧!---------------')
punch=['石头','剪刀','布']
computer_choice=random.choice(punch)
user_choice=''
user_choice=input('你的出拳是?(剪刀、石头、布)')
while (user_choice not in punch):
print('出拳有误,请重新输入。')
user_choice=input()
# 亮拳
print('\n-------------战斗--------------')
print('电脑的选择是:%s'%computer_choice)
print('你的选择是:%s'%user_choice)
# 胜负
print('\n-------------结果--------------')
if user_choice==computer_choice:
print('平局')
elif user_choice==punch[punch.index(computer_choice)-1]:
print('你赢啦')
else:
print('你输啦')