这个练习是个小游戏,很经典,通常非常适合计算机语言学习中的控制语句入门。
游戏规则为:首先系统自动产生一个1到100之间的随机整数,允许用户通过输入多次猜测,并每次都进行大小提醒,直至猜中为止。
编程其实就是要告诉计算机该怎么处理这个逻辑,因此首先需要自己对这个游戏的流程处理做出一个清晰的描述,我们不妨以伪代码的方式来给出一个步骤:
设置一个随机数
输入猜数
如果猜数大了,输出大了
如果猜数小了,输出小了
如果猜数相等,输出成功,并退出
...
显然如果用户没有猜中,还需要继续输入猜数,因此可能的步骤为:
设置一个随机数
输入猜数
如果猜数大了,输出大了
如果猜数小了,输出小了
如果猜数相等,输出成功,并退出
输入猜数
如果猜数大了,输出大了
如果猜数小了,输出小了
如果猜数相等,输出成功,并退出
输入猜数
如果猜数大了,输出大了
如果猜数小了,输出小了
如果猜数相等,输出成功,并退出
...
显然这是个循环问题,循环的内容就是输入猜数到三种不同的判断,但是循环的次数并不能确定,它只能依赖用户是否猜中,只有没猜中才需要继续循环,因此完整的步骤应该为:
设置一个随机数
循环(不固定次数的循环)
输入猜数
如果猜数大了,输出大了
如果猜数小了,输出小了
如果猜数相等,输出成功,并退出
有前面学习的经验,就会看出来这个循环应该是while,里面的如果就是if。这些并不十分难做。不过,如何得到一个随机数呢?
但凡遇到此类问题,可以想象,Python一定提供了相应的方法,而无需我们自己来做(其实真正实现一个随机数并不容易)。利用互联网搜索也可以很快了解到,比如利用random模块:
import random
print(random.randint(1, 6))
每次运行,都会输出一个1到6(含1和6)的随机整数。random字面就是随机的意思,randint函数字面就是随机整数的意思。
按照刚才的伪代码,对应着,代码可以写为:
可以复制的代码为:
import random
randNum = random.randint(1, 100)
while True:
num = int(input())
if num < randNum:
print('小了')
elif num > randNum:
print('大了')
else:
print('猜中')
break
这个循环采取了一个较为简单的实现方法,就是始终为真,只要猜中就退出,从而可以结束循环。
大家试一试,如何能更快的猜中呢?随便猜?从1到100挨个猜?折半猜(比如首先猜50,如果提示大了,就输入25,如果又提示小了,就再输入37,等等)。大家可以自己来判断下哪一种方法更为合理。
语句的次序很重要,有人写成这个样子,将输入猜数和判断猜数交换了位置:
import random
randNum = random.randint(1, 100)
while True:
if num < randNum:
print('小了')
elif num > randNum:
print('大了')
else:
print('猜中')
break
num = int(input())
运行界面为:
显然,由于在第四行进行num和randNum大小判断时,由于还没有num的数值,因此出现了num没有定义的常见错误。当然,不是说,这个输入猜数和判断猜数就一定不能交换位置,也可以通过下面的方法来解决:
import random
randNum = random.randint(1, 100)
num = int(input())
while True:
if num < randNum:
print('小了')
elif num > randNum:
print('大了')
else:
print('猜中')
break
num = int(input())
这里在第三行、循环语句的前面增加了一个输入猜数的语句,虽然重复写了两次输入猜数的语句,但是也可以实现相同的目的。
不过,既然循环就已经知道了输入的猜数,那么为什么还使用True来控制循环条件呢?这里其实展示了一种新的思路,即将用户输入不等于随机数作为循环条件:
import random
randNum = random.randint(1, 100)
num = int(input())
while num != randNum:
if num < randNum:
print('小了')
else:
print('大了')
num = int(input())
print('猜中')
注意一点,由于在循环里面,是不可能实现两个数值相等的,因此就无需在循环内判断是否相同并输出“猜中”,相反,结束循环即表示猜中了,因此在循环后可以表达“猜中”的输出。
当然,为了防止以后不小心在循环结束后和输出“猜中”前增加其他代码,还可以使用else来强制循环一结束即可运行输出“猜中”的代码:
import random
randNum = random.randint(1, 100)
num = int(input())
while num != randNum:
if num < randNum:
print('小了')
else:
print('大了')
num = int(input())
else:
print('猜中')
我们还是回到最先的版本上来:
import random
randNum = random.randint(1, 100)
while True:
num = int(input())
if num < randNum:
print('小了')
elif num > randNum:
print('大了')
else:
print('猜中')
break
接下来,我们准备将问题稍微复杂一些,其实我们在输入猜数的时候,很容易因为输入不合规导致代码运行失败,比如输入小数、字符(如abcd)或者什么都不输入直接回车,大家都会发现代码运行出错了:
或者输入-1,似乎代码也能运行,但是不应该允许用户输入小于1或者大于100的数:
因此,良好的代码应该能判断下输入的内容是否合规。我们一个一个来,先处理-1和101的问题:
import random
randNum = random.randint(1, 100)
while True:
num = int(input())
if num >= 1 and num <= 100:
if num < randNum:
print('小了')
elif num > randNum:
print('大了')
else:
print('猜中')
break
else:
print('请输入1到100的整数!')
这个处理比较简答,就是在现有的大小判断外,再增加一个猜数数值的范围判断,只有在范围之内的再去考虑大小判断。
关于如何判断是否输入的数字,不妨搜索下:
很多初学者对于这种边搜索边学习的方法感到困惑,觉得应该全部学习好后,才能编程。其实,对于编程,在学习完基本知识后,通过边上机边搜索的方法,学习非常快,也是很多人的方法。
这里很快就能知道一种常见的函数isdigit,在刚才代码判断数值范围的外面再增加一个是否为数字的判断:
import random
randNum = random.randint(1, 100)
while True:
num = input()
if num.isdigit():
num = int(num)
if num >= 1 and num <= 100:
if num < randNum:
print('小了')
elif num > randNum:
print('大了')
else:
print('猜中')
break
else:
print('请输入1到100的整数!')
else:
print('请输入正确的整数!')
但是,对于这种输入数值的判断,isdigit函数还是有点简单,比如你会发现当你输入-1时,它居然出现和输入非数字一样的提示(正确的提示应该是“请输入1到100的整数!”):
原因只能说明-1在遇到isdigit函数判断时就被认为不是数字,因为负号它认为不是数字!这不是我们的问题,而是isdigit函数过于简单造成的。当然我们可以去查找或者自己设计一些更为强大的判断数字函数来替换isdigit,这些留给大家来完成。
不过,更为强大的方法考虑使用异常处理:
import random
randNum = random.randint(1, 100)
while True:
num = input()
try:
num = int(num)
if num >= 1 and num <= 100:
if num < randNum:
print('小了')
elif num > randNum:
print('大了')
else:
print('猜中')
break
else:
print('请输入1到100的整数!')
except ValueError:
print('请输入正确的整数!')
这个不做要求,对于部分有兴趣的同学可以关注下。这个代码后期在学习完异常处理后,你会发现它非常简单高效!
配套学习资源、慕课视频: