177.md 5.9 KB
Newer Older
W
wizardforcel 已提交
1
# Python 3:猜数字 – 回顾
W
init  
wizardforcel 已提交
2 3 4

> 原文: [https://javabeginnerstutorial.com/python-tutorial/python-3-guess-the-number-the-return/](https://javabeginnerstutorial.com/python-tutorial/python-3-guess-the-number-the-return/)

W
wizardforcel 已提交
5
我们之前已经看过这个示例。 在那里,我包括了很多处理用户输入和主要逻辑的循环……现在该重构应用以使用功能了。 这应该使代码易于阅读,以后我们可以重用部分代码。
W
init  
wizardforcel 已提交
6 7 8 9 10

这些可重复使用的部分之一是数字读数。 我们有两个要点,我们希望用户输入数字并编写了略微相同的代码。 这是开始重构并将其提取为一个功能的好地方。

因此,让我们将其提取为一个函数。 唯一的区别是我们打印出的询问用户输入数字的消息。 可以将其作为函数的参数来处理,因为这是唯一的可变部分。 因此,让我们看一下函数的定义:

W
wizardforcel 已提交
11
```py
W
init  
wizardforcel 已提交
12 13 14 15 16 17 18 19 20 21 22
def ask_user_for_number(message_text):
 while True:
       try:
           return int(input(message_text))
       except ValueError:
           print("This was not a number!")
           continue
```

如您所见,这是一种非常简单的方法,我们要求用户输入内容,如果输入的是数字,则将其返回。

W
wizardforcel 已提交
23
自然,我们无法使用此方法处理将数字验证为 100 或 1000 的情况,因此我们也必须在那里修改代码块。
W
init  
wizardforcel 已提交
24

W
wizardforcel 已提交
25
在此简单修改的​​最后,我们为应用提供了以下代码(并且具有相同的功能):
W
init  
wizardforcel 已提交
26

W
wizardforcel 已提交
27
```py
W
init  
wizardforcel 已提交
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
__author__ = 'GHajba'

import random

def ask_user_for_number(message_text):
   while True:
       try:
           return int(input(message_text))
       except ValueError:
           print("This was not a number!")
          continue
       return number

while True:
   max_number = 0
   while max_number != 100 and max_number != 1000:
       max_number = ask_user_for_number('Should the secret number between 1 and 100 or 1 and 1000? ')

   if max_number == 100:
      guess_count = 7
   else:
       guess_count = 10

   print('You have chosen {}, you will have {} guesses to find the secret number.'.format(max_number, guess_count))

   secret_number = random.randint(1, max_number)

   print('I have chosen the secret number...')

   guesses = 0

   while guess_count - guesses:
       guesses += 1
       guessed = ask_user_for_number("What's your guess? ")
       if guessed == secret_number:
           print('Congrats, you have Won!')
           break
        elif guessed > secret_number:
           print('The secret number is lower...')
       else:
           print('The secret number is higher...')
   else:
       print("Sorry, you lose.")

   print("The secret number was ", secret_number)
   answer = ''
   while answer.lower() not in ['yes', 'no', 'y', 'n']:
       answer = input("Do you want to play another round? (yes / no) ")

   if 'no' == answer or 'n' == answer:
       break
```

看起来很不错,没有重复的代码,而且非常精简。 但是,如果您对测试有所了解,您可能会说这段代码有一个很大的“主”块,很难测试。

我必须同意。 单元测试(尽管我将在下一章中进行介绍)在这里会很麻烦。 解决方案是将这个较大的主循环拆分为较小的功能,这些功能可以单独进行测试。

W
wizardforcel 已提交
85
例如,求值用户是赢还是输。 为此,我们可以编写一个函数,该函数将秘密数字,猜测,猜测计数和猜测数字作为输入,并对消息进行求值以告知用户。 但是一个函数的四个参数很多,因此现在让我们对其进行划分。 基于这些输入,我将创建一个函数来告诉用户秘密数字是猜中的数字是更高还是更低。
W
init  
wizardforcel 已提交
86

W
wizardforcel 已提交
87
```py
W
init  
wizardforcel 已提交
88 89 90 91 92 93 94 95 96 97
def user_won(guessed, secret):
   if guessed == secret_number:
       print('Congrats, you have Won!')
       return True
   if guessed > secret_number:
       print('The secret number is lower...')
   else:
       print('The secret number is higher...')
```

W
wizardforcel 已提交
98
`user_won`函数中,我们使用`return`语句指示用户是否赢了。 如果不是,则返回隐式`None`,其结果为`false`
W
init  
wizardforcel 已提交
99 100 101

我们可以测试的另一件事是询问用户是否要再玩一轮。

W
wizardforcel 已提交
102
```py
W
init  
wizardforcel 已提交
103 104 105 106 107 108 109 110 111 112
def want_continue():
   answer = ''
   while answer.lower() not in ['yes', 'no', 'y', 'n']:
       answer = input("Do you want to play another round? (yes / no) ")

   return answer in ['yes','y']
```

完成所有这些更改后,让我再次向您显示完整代码:

W
wizardforcel 已提交
113
```py
W
init  
wizardforcel 已提交
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
__author__ = 'GHajba'

import random

def ask_user_for_number(message_text):
   while True:
       try:
           return int(input(message_text))
       except ValueError:
           print("This was not a number!")
            continue
       return number

def user_won(guessed, secret):
   if guessed == secret_number:
       print('Congrats, you have Won!')
       return True
   if guessed > secret_number:
       print('The secret number is lower...')
   else:
        print('The secret number is higher...')

def want_continue():
   answer = ''
   while answer.lower() not in ['yes', 'no', 'y', 'n']:
       answer = input("Do you want to play another round? (yes / no) ")

   return answer in ['yes','y']

while True:
   max_number = 0
   while max_number != 100 and max_number != 1000:
       max_number = ask_user_for_number('Should the secret number between 1 and 100 or 1 and 1000? ')

   if max_number == 100:
       guess_count = 7
   else:
       guess_count = 10

   print('You have chosen {}, you will have {} guesses to find the secret number.'.format(max_number, guess_count))

   secret_number = random.randint(1, max_number)

   print('I have chosen the secret number...')

   guesses = 0

   while guess_count - guesses:
       guesses += 1
       guessed = ask_user_for_number("What's your guess? ")
       if user_won(guessed, secret_number):
           break
   else:
       print("Sorry, you lose.")

   print("The secret number was ", secret_number)
   if not want_continue():
       break
```