如何提高代码的可读性?意大利面条代码(我是初学者)
How can I improve my code readability? Spaghetti Code (I'm a beginner)
我需要帮助,除了帮助我,人们还告诉我我的代码虽然可以工作,但一团糟,属于“意大利面条代码”类别。
有人可以协助我如何重构我的代码以提高效率和可读性吗?
非常感谢您能给我的任何帮助。
这是我的代码:Python
上的刽子手游戏
import random
import time
from theHangmanStages import * # This imports ASCII hangman figure.
from theHangmanIntro import *
intro() # This just imports an ASCII art as an intro.
startGame = input()
game = 'on'
words = ''' In a strange city lying alone
Far down within the dim West
Where the good and the bad and the worst and the best
Have gone to their eternal rest
There shrines and palaces and towers'''.lower().split()
secretWord = random.sample(words, 1)
numberOFLetters = len(secretWord[0])
missedLetters = ''
alreadyGuessed = ''
print('I\'m thinking of a word...')
time.sleep(1)
print(f'\nThe word has {numberOFLetters} letters...')
for char in secretWord[0]:
print('_ ', end='')
wordSpaces = len(secretWord[0]) * '_'
listedWordSpaces = list(wordSpaces)
def char_positioner(word, guessAttempt):
i = word.index(guessAttempt)
if guessAttempt in word:
listedWordSpaces[i] = word[i]
print(listedWordSpaces)
return listedWordSpaces
def converter(list):
# Converts a list of chars into a string.
initialStr = ''
for char in list:
initialStr += char
print(initialStr)
return initialStr
def getGuess(guess):
# Returns the letter the played entered. This function makes sure the
# player entered a single letter and not something else.
while True:
guess = guess.lower()
if len(guess) != 1:
print('Please enter a single letter.')
guess = input()
elif guess in alreadyGuessed:
print('You have already guessed that letter')
guess = input()
elif guess not in 'abcdefghijklmnopqrstuvwxyz':
print('Please enter a letter.')
else:
return guess
misses = 0
while game == 'on':
print('\nChoose a letter')
chosenLetter = input()
guess = getGuess(chosenLetter)
if guess in secretWord[0]:
print('\nYour guess is correct!')
alreadyGuessed += guess
position = char_positioner(secretWord[0], guess)
converter(position)
elif guess not in secretWord[0]:
print('\nWrong letter, try again.')
missedLetters += guess
alreadyGuessed += guess
print('\nMissed letters: ', missedLetters, end=' ')
misses += 1
if misses == 1:
hangmanOne()
elif misses == 2:
hangmanTwo()
elif misses == 3:
hangmanThree()
elif misses == 4:
hangmanFour()
elif misses == 5:
hangmanFive()
elif misses == 6:
hangmanSix()
print('You lose! - The word was:' + '"' + secretWord[0] + '"')
break
else:
print('Wrong input.')
我偶然发现
secretWord = random.sample(words, 1)
我的期望是 secretWord
是一个词(即一个字符串)。但是,您始终使用 [0]
访问它。我不得不在调试器中查看 secretWord
是一个包含 1 个单词的列表。这违反了 Clean Code“最小惊讶原则”和“不要重复自己”(您需要在多个地方重复索引器 [0]
)。
numberOFLetters
应该是 numberOfLetters
.
您已经计算出字母的数量,但没有始终如一地使用它。 wordSpaces = len(secretWord) * '_'
可以是 wordSpaces = numberOfLetters * '_'
.
与计算 wordSpaces = numberOfLetters * '_'
的方式相同,您可以摆脱循环打印下划线:
for char in secretWord:
print('_ ', end='')
可能是
print(numberOfLetters * '_ ')
你有
listedWordSpaces = list(wordSpaces)
其中 wordSpaces
是包含下划线的字符串。字符串已经是 char
的列表。对我来说,这听起来很重复,违反了 KISS(“保持简单和愚蠢”)和 YAGNI(“你不需要它”)原则。其实decision好像是逼着你多写代码:def converter(list):
是反转操作
顺便说一句,这不仅是一个函数,它还有一个副作用:它打印字符串。并且从未使用 return 值。此外,该方法比需要的更复杂。 initialStr = ''.join(list)
应该给出相同的结果。
类似的打印副作用在 def char_positioner(word, guessAttempt):
中。使用时的变量名称是 position = char_positioner(secretWord, guess)
,我希望 position
是一个 int
,但显然它是一个字符列表。真令人困惑。
您在这一行中违反了 PEP 8:
misses = 0
因为函数定义后应该有 2 个换行符。
这里还有一个 PEP 8 问题,运算符周围有间距:
print('You lose! - The word was:' + '"' + secretWord[0] + '"')
最后可能缺少换行符(不过可能是 SO copy/paste 问题)。
你还有几个shadowing issues:
def converter(list): [...]
for char in list: [...]
def getGuess(guess): [...]
我在这里也看到了一个 DRY(“不要重复你自己”)问题:
if misses == 1:
hangmanOne()
[...]
想象一个更复杂的刽子手。你会写 100 个方法和 100 个 if/else 语句吗?
一些函数名像名词一样命名,但应该是动词:
def converter(list): [...]
def char_positioner(word, guessAttempt): [...]
就我个人而言,我希望看到 type hints,这样我可以更好地理解参数的预期类型是什么以及 return 类型是什么。
我明白了while game == 'on':
。通常我们不会在这里使用字符串,而是使用布尔值。似乎也没有办法通过转动它来停止游戏"off"
。退出案例是通过 break
实现的,因此目前这可能是一个 while True
循环。随着游戏的发展,break
语句有点脆弱,可能不再跳出最外层循环。 while isPlaying
或 while not isGameOver
之类的布尔条件可能是更好的选择。
我需要帮助,除了帮助我,人们还告诉我我的代码虽然可以工作,但一团糟,属于“意大利面条代码”类别。
有人可以协助我如何重构我的代码以提高效率和可读性吗?
非常感谢您能给我的任何帮助。
这是我的代码:Python
上的刽子手游戏import random
import time
from theHangmanStages import * # This imports ASCII hangman figure.
from theHangmanIntro import *
intro() # This just imports an ASCII art as an intro.
startGame = input()
game = 'on'
words = ''' In a strange city lying alone
Far down within the dim West
Where the good and the bad and the worst and the best
Have gone to their eternal rest
There shrines and palaces and towers'''.lower().split()
secretWord = random.sample(words, 1)
numberOFLetters = len(secretWord[0])
missedLetters = ''
alreadyGuessed = ''
print('I\'m thinking of a word...')
time.sleep(1)
print(f'\nThe word has {numberOFLetters} letters...')
for char in secretWord[0]:
print('_ ', end='')
wordSpaces = len(secretWord[0]) * '_'
listedWordSpaces = list(wordSpaces)
def char_positioner(word, guessAttempt):
i = word.index(guessAttempt)
if guessAttempt in word:
listedWordSpaces[i] = word[i]
print(listedWordSpaces)
return listedWordSpaces
def converter(list):
# Converts a list of chars into a string.
initialStr = ''
for char in list:
initialStr += char
print(initialStr)
return initialStr
def getGuess(guess):
# Returns the letter the played entered. This function makes sure the
# player entered a single letter and not something else.
while True:
guess = guess.lower()
if len(guess) != 1:
print('Please enter a single letter.')
guess = input()
elif guess in alreadyGuessed:
print('You have already guessed that letter')
guess = input()
elif guess not in 'abcdefghijklmnopqrstuvwxyz':
print('Please enter a letter.')
else:
return guess
misses = 0
while game == 'on':
print('\nChoose a letter')
chosenLetter = input()
guess = getGuess(chosenLetter)
if guess in secretWord[0]:
print('\nYour guess is correct!')
alreadyGuessed += guess
position = char_positioner(secretWord[0], guess)
converter(position)
elif guess not in secretWord[0]:
print('\nWrong letter, try again.')
missedLetters += guess
alreadyGuessed += guess
print('\nMissed letters: ', missedLetters, end=' ')
misses += 1
if misses == 1:
hangmanOne()
elif misses == 2:
hangmanTwo()
elif misses == 3:
hangmanThree()
elif misses == 4:
hangmanFour()
elif misses == 5:
hangmanFive()
elif misses == 6:
hangmanSix()
print('You lose! - The word was:' + '"' + secretWord[0] + '"')
break
else:
print('Wrong input.')
我偶然发现
secretWord = random.sample(words, 1)
我的期望是 secretWord
是一个词(即一个字符串)。但是,您始终使用 [0]
访问它。我不得不在调试器中查看 secretWord
是一个包含 1 个单词的列表。这违反了 Clean Code“最小惊讶原则”和“不要重复自己”(您需要在多个地方重复索引器 [0]
)。
numberOFLetters
应该是 numberOfLetters
.
您已经计算出字母的数量,但没有始终如一地使用它。 wordSpaces = len(secretWord) * '_'
可以是 wordSpaces = numberOfLetters * '_'
.
与计算 wordSpaces = numberOfLetters * '_'
的方式相同,您可以摆脱循环打印下划线:
for char in secretWord:
print('_ ', end='')
可能是
print(numberOfLetters * '_ ')
你有
listedWordSpaces = list(wordSpaces)
其中 wordSpaces
是包含下划线的字符串。字符串已经是 char
的列表。对我来说,这听起来很重复,违反了 KISS(“保持简单和愚蠢”)和 YAGNI(“你不需要它”)原则。其实decision好像是逼着你多写代码:def converter(list):
是反转操作
顺便说一句,这不仅是一个函数,它还有一个副作用:它打印字符串。并且从未使用 return 值。此外,该方法比需要的更复杂。 initialStr = ''.join(list)
应该给出相同的结果。
类似的打印副作用在 def char_positioner(word, guessAttempt):
中。使用时的变量名称是 position = char_positioner(secretWord, guess)
,我希望 position
是一个 int
,但显然它是一个字符列表。真令人困惑。
您在这一行中违反了 PEP 8:
misses = 0
因为函数定义后应该有 2 个换行符。
这里还有一个 PEP 8 问题,运算符周围有间距:
print('You lose! - The word was:' + '"' + secretWord[0] + '"')
最后可能缺少换行符(不过可能是 SO copy/paste 问题)。
你还有几个shadowing issues:
def converter(list): [...]
for char in list: [...]
def getGuess(guess): [...]
我在这里也看到了一个 DRY(“不要重复你自己”)问题:
if misses == 1:
hangmanOne()
[...]
想象一个更复杂的刽子手。你会写 100 个方法和 100 个 if/else 语句吗?
一些函数名像名词一样命名,但应该是动词:
def converter(list): [...]
def char_positioner(word, guessAttempt): [...]
就我个人而言,我希望看到 type hints,这样我可以更好地理解参数的预期类型是什么以及 return 类型是什么。
我明白了while game == 'on':
。通常我们不会在这里使用字符串,而是使用布尔值。似乎也没有办法通过转动它来停止游戏"off"
。退出案例是通过 break
实现的,因此目前这可能是一个 while True
循环。随着游戏的发展,break
语句有点脆弱,可能不再跳出最外层循环。 while isPlaying
或 while not isGameOver
之类的布尔条件可能是更好的选择。