Python Programming for the Absolute Beginner, 3rd Edition

With the basics of files and exceptions under your belt, it's time to tackle the Trivia Challenge game presented at the beginning of the chapter. One of the cool things about the program is that it reads a plain text file, so you can create your own trivia game episodes with a text editor and a dash of creativity. As you'll see in the code, the text file the program reads, trivia.txt, needs to be in the same directory as the program file. To create your own episode full of questions, all you need to do is replace this file with one containing your own work.

Understanding the Data File Layout

Before I go over actual code from the game, you should understand exactly how the trivia.txt file is structured. The very first line in the file is the title of the episode. The rest of the file consists of blocks of seven lines for each question. You can have as many blocks (and thus questions) as you like. Here's a generic representation of a block:

<category> <question> <answer 1> <answer 2> <answer 3> <answer 4> <correct answer> <explanation>

And here's the beginning of the file I created for the game:

An Episode You Can't Refuse On the Run With a Mammal Let's say you turn state's evidence and need to "get on the lamb." If you wait /too long, what will happen? You'll end up on the sheep You'll end up on the cow You'll end up on the goat You'll end up on the emu 1 A lamb is just a young sheep. The Godfather Will Get Down With You Now Let's say you have an audience with the Godfather of Soul. How would it be /smart to address him? Mr. Richard Mr. Domino Mr. Brown Mr. Checker 3 James Brown is the Godfather of Soul.

To save space, I only show the first 15 lines of the file—two questions' worth. You can take a look at the complete file, trivia.txt, on the CD-ROM that's included with this book.

Remember, the very first line in the file, An Episode You Can't Refuse, is the episode title for this game. The next seven lines are for the first question. And the next seven lines are for the second question. So, the line On the Run With a Mammal is the category of the first question. The category is just a clever way to introduce the next question. The next line, Let's say you turn state's evidence and need to "get on the lamb." If you wait /too long, what will happen?, is the first question in the game. The next four lines, You'll end up on the sheep, You'll end up on the cow, You'll end up on the goat, and You'll end up on the emu, are the four possible answers from which the player will choose. The next line, 1, is the number of the correct answer. So in this case, the correct answer to the question is the first answer, You'll end up on the sheep. The next line, A lamb is just a young sheep., explains why the correct answer is correct. The rest of the questions follow the same pattern.

An important thing to note is that I included a forward slash (/) in two of the lines. I did this to represent a newline since Python does not automatically wrap text when it prints it. When the program reads a line from the text file, it replaces all of the forward slashes with the newline character. You'll see exactly how the program does this when I go over the code.

The open_file() Function

The first thing I do in the program is define the function open_file(), which receives a file name and mode (both strings) and returns a corresponding file object. I use try and except to trap for an IOError exception for input-output errors, which would occur if the file doesn't exist, for example.

If I trap an exception, that means there was a problem opening the trivia file. If this happens, there's no point in continuing the program, so I print an appropriate message and call the sys.exit() function. This function raises an exception that results in the termination of the program. You should only use sys.exit() as a last resort, when you must end a program. Notice that I didn't have to import the sys module to call sys.exit(). That's because the sys module is always available.

# Trivia Challenge # Trivia game that reads a plain text file # Michael Dawson - 5/3/03 def open_file(file_name, mode): """Open a file.""" try: the_file = open(file_name, mode) except(IOError), e: print "Unable to open the file", file_name, "Ending program.\n", e raw_input("\n\nPress the enter key to exit.") sys.exit() else: return the_file

The next_line() Function

Next, I define the next_line() function, which receives a file object and returns the next line of text from it:

def next_line(the_file): """Return next line from the trivia file, formatted.""" line = the_file.readline() line = line.replace("/", "\n") return line

However, I do one small bit of formatting to the line before I return it. I replace all forward slashes with newline characters. I do this because Python does not automatically word wrap printed text. My procedure gives the creator of a trivia text file some formatting control. He or she can indicate where newlines should go so that words don't get split across lines. Take a look at the triva.txt file and the output of the Trivia Challenge game to see this in action. Try removing the forward slashes from the text file and check out the results.

The next_block() Function

The next_block() function reads the next block of lines for one question. It takes a file object and returns four strings and a list of strings. It returns a string for the category, question, correct answer, and explanation. It returns a list of four strings for the possible answers to the question.

def next_block(the_file): """Return the next block of data from the trivia file.""" category = next_line(the_file) question = next_line(the_file) answers = [] for i in range(4): answers.append(next_line(the_file)) correct = next_line(the_file) if correct: correct = correct[0] explanation = next_line(the_file) return category, question, answers, correct, explanation

If the end of the file is reached, reading a line returns the empty string. So, when the program comes to the end of trivia.txt, category gets the empty string. I check category in the main() function of the program. When it becomes the empty string, the game is over.

The welcome() Function

The welcome() function welcomes the player to the game and announces the episode's title. The function gets the episode title as a string and prints it along with a welcome message.

def welcome(title): """Welcome the player and get his/her name.""" print "\t\tWelcome to Trivia Challenge!\n" print "\t\t", title, "\n"

Setting Up the Game

Next, I create the main() function, which houses the main game loop. In the first part of the function, I set up the game by opening the trivia file, getting the title of the episode (the first line of the file), welcoming the player, and setting the player's score to 0.

def main(): trivia_file = open_file("trivia.txt", "r") title = next_line(trivia_file) welcome(title) score = 0

Asking a Question

Next, I read the first block of lines for the first question into variables. Then, I start the while loop, which will continue to ask questions as long as category is not the empty string. If category is the empty string, that means the end of the trivia file has been reached and the loop won't be entered. I ask a question by printing the category of the question, the question itself, and the four possible answers.

# get first block category, question, answers, correct, explanation = next_block(trivia_file) while category: # ask a question print category print question for i in range(4): print "\t", i + 1, "-", answers[i]

Getting an Answer

Next, I get the player's answer:

# get answer answer = raw_input("What's your answer?: ")

Checking an Answer

Then, I compare the player's answer to the correct answer. If they match, the player is congratulated and his or her score is increased by one. If they don't match, the player is told he or she is wrong. In either case, I then display the explanation, which describes why the correct answer is correct. Lastly, I display the player's current score.

# check answer if answer == correct: print "\nRight!", score += 1 else: print "\nWrong.", print explanation print "Score:", score, "\n\n"

Getting the Next Question

Then, I call the next_block() function and get the block of strings for the next question. If there are no more questions, category will get the empty string and the loop won't continue.

# get next block category, question, answers, correct, explanation = next_block(trivia_file)

Ending the Game

After the loop, I close the trivia file and display the player's score:

trivia_file.close() print "That was the last question!" print "You're final score is:", score

Starting the main() Function

The last lines of code start main() and kick off the game:

main() raw_input("\n\nPress the enter key to exit.")

Категории