patternpythonMinor
First Python script: number-guessing game with a global variable
Viewed 0 times
scriptglobalnumberwithfirstgamepythonguessingvariable
Problem
This is my first Python script, and I was hoping to get some feedback. I do have one specific question: is the use of
I also realize that the below code is more complex than it needs to be. I know that it could be written in much fewer lines of code by removing function definitions and such (in fact, my first version was only like 15 lines). But I wrote this more complicated version in order to get a handle on some of the basic concepts like sharing variables, returning from functions, etc.
Any tips or glaring style/best-practices issues are appreciated! (I'm a style-Nazi with Java, so please, don't hold back so that I can learn!)
```
#!/usr/bin/python
from random import randint
# GLOBALS
guesses = 0
the_number = 0
def checkGuess(guess):
global the_number
if guess the_number:
print "The number is LOWER."
return False
def isValid(guess):
return len(guess) > 0 and guess.isdigit()
def getInput():
global guesses
input = ""
while not isValid(input):
input = raw_input("(#" + str(guesses) + ") Guess a number: ")
if not isValid(input):
print "Please guess an integer!"
return int(input)
def runGame(min, max):
global guesses
global the_number
the_number = randint(min, max)
guess = 0
print "I'm thinking of a number between " + str(min) + " and " + str(max) + " ..."
while not checkGuess(guess):
guesses = guesses + 1
guess = getInput()
print "YOU WON!"
def printTitle():
global variables considered a bad practice? When I used them below, my programmer's instincts immediately went off as though I was creating a code-smell, mostly because it seems much less elegant than just having a private String myVariable at the top of a Java class. The use of global myVariable to force the scope seemed a bit hacky. But I don't know a single thing about Python except what I wrote below, so I could be way off.I also realize that the below code is more complex than it needs to be. I know that it could be written in much fewer lines of code by removing function definitions and such (in fact, my first version was only like 15 lines). But I wrote this more complicated version in order to get a handle on some of the basic concepts like sharing variables, returning from functions, etc.
Any tips or glaring style/best-practices issues are appreciated! (I'm a style-Nazi with Java, so please, don't hold back so that I can learn!)
```
#!/usr/bin/python
from random import randint
# GLOBALS
guesses = 0
the_number = 0
def checkGuess(guess):
global the_number
if guess the_number:
print "The number is LOWER."
return False
def isValid(guess):
return len(guess) > 0 and guess.isdigit()
def getInput():
global guesses
input = ""
while not isValid(input):
input = raw_input("(#" + str(guesses) + ") Guess a number: ")
if not isValid(input):
print "Please guess an integer!"
return int(input)
def runGame(min, max):
global guesses
global the_number
the_number = randint(min, max)
guess = 0
print "I'm thinking of a number between " + str(min) + " and " + str(max) + " ..."
while not checkGuess(guess):
guesses = guesses + 1
guess = getInput()
print "YOU WON!"
def printTitle():
Solution
Some notes:
-
Mutable global state is a bad programming practice. Instead, pass values as arguments so functions are black boxes that take values (as arguments) and return values. If such a function does not perform any side-effect (print to console, write a file, ...), then it's a "pure function". Try to write pure functions whenever possible.
-
Conditionals: Don't write a fallback (
-
Use
-
Try to use Python 3 whenever possible.
I'd write:
-
Mutable global state is a bad programming practice. Instead, pass values as arguments so functions are black boxes that take values (as arguments) and return values. If such a function does not perform any side-effect (print to console, write a file, ...), then it's a "pure function". Try to write pure functions whenever possible.
-
Conditionals: Don't write a fallback (
return False) where some branches get and others don't. Non-overlapping conditionals are more clear.-
Use
name_of_variable and name_of_function. -
Try to use Python 3 whenever possible.
I'd write:
from random import randint
from itertools import count
def is_guess_correct(number, guess):
if guess == number:
return True
elif guess < number:
print("The number is HIGHER.")
return False
else:
print("The number is LOWER.")
return False
def is_valid_guess(number_string):
return number_string.isdigit()
def get_number(guess_iteration):
while 1:
number_string = input("({0}) Guess a number: ".format(guess_iteration))
if is_valid_guess(number_string):
return int(number_string)
else:
print("Please enter a valid integer!")
def run_game(nmin, nmax):
number = randint(nmin, nmax)
print("I'm thinking of a number between {0} and {1}...".format(nmin, nmax))
for guess_iteration in count(1):
guess = get_number(guess_iteration)
if is_guess_correct(number, guess):
print("YOU WON!")
break
if __name__ == '__main__':
run_game(1, 100)Code Snippets
from random import randint
from itertools import count
def is_guess_correct(number, guess):
if guess == number:
return True
elif guess < number:
print("The number is HIGHER.")
return False
else:
print("The number is LOWER.")
return False
def is_valid_guess(number_string):
return number_string.isdigit()
def get_number(guess_iteration):
while 1:
number_string = input("({0}) Guess a number: ".format(guess_iteration))
if is_valid_guess(number_string):
return int(number_string)
else:
print("Please enter a valid integer!")
def run_game(nmin, nmax):
number = randint(nmin, nmax)
print("I'm thinking of a number between {0} and {1}...".format(nmin, nmax))
for guess_iteration in count(1):
guess = get_number(guess_iteration)
if is_guess_correct(number, guess):
print("YOU WON!")
break
if __name__ == '__main__':
run_game(1, 100)Context
StackExchange Code Review Q#30150, answer score: 5
Revisions (0)
No revisions yet.