I've read about keeping functions to the same level of abstraction, and it seems to make sense in all the examples. However, when translating to non-contrived programming, I'm still very unsure of my decisions. I'm especially unsure of where it applies. I wrote this guessing game to try to work on it, but it ended up feeling really clunky and redundant. How far should I go out of my way to flatten code? I read loops should ideally only be one function call, but that seems extreme. Is that really standard practice? If so, how would I refactor my main without needing a bunch of globals or really long parameter lists?
from random import randrange
DEFAULT_LO = 1
DEFAULT_HI = 100
HOT_DISTANCE = 10
def main():
answer = randrange(DEFAULT_LO, DEFAULT_HI+1)
tries = 1
lastGuess = 0
guess = 0
wasHot = False
won = False
isFirstTry = True
while (not won):
lastGuess = guess
guess = promptGuess()
if validGuess(guess):
if guess != answer:
newDistance = abs(answer-guess)
oldDistance = abs(answer-lastGuess)
displayResult(newDistance, oldDistance, isFirstTry)
else:
displayWin(tries)
won = True
tries += 1
isFirstTry = False
def promptGuess(lo=DEFAULT_LO, hi=DEFAULT_HI):
guess = input('Enter a number ({}-{}): '.format(lo, hi))
guess = int(guess)
return guess
def validGuess(num, lo=DEFAULT_LO, hi=DEFAULT_HI):
return (num >= lo and num <= hi)
def displayResult(newDistance, oldDistance, firstGuess):
wasHot = (oldDistance <= HOT_DISTANCE)
isHot = (newDistance <= HOT_DISTANCE)
if firstGuess:
displayHotCold(newDistance)
elif newDistance is oldDistance: # Can happen with new answer if equally
print('Same temperature!') # far on opposite side of answer
elif isHot:
displayHotHotterCooler(newDistance, oldDistance, wasHot)
else:
displayColdWarmerColder(newDistance, oldDistance, wasHot)
def displayHotCold(newDistance):
if newDistance <= HOT_DISTANCE:
print('HOT!')
else:
print('Cold')
def displayHotHotterCooler(newDistance, oldDistance, wasHot):
if not wasHot:
print('HOT!!')
elif newDistance < oldDistance:
print('HOTTER!!!')
else:
print('COOLER')
def displayColdWarmerColder(newDistance, oldDistance, wasHot):
if wasHot:
print('COLD')
elif newDistance < oldDistance:
print('Warmer!')
else:
print('Colder')
def displayWin(tries):
if tries is 1:
print('WOW!! You got it on your first try!')
else:
print('GOOD JOB! You got it in {} tries.'.format(tries))
main()