-2

I have some code which chooses a random word from a list of words and displays it on a label. The user then has to retype this word correctly to score a point. I decided to use a text file to store the words and read it into a list in the program but this is causing problems.

try:
    from tkinter import *
except ImportError:
    from Tkinter import *

import random

with open("WORDS_FILE.txt") as f:
    WORDS = list(f.readlines())

word_count = 0

def shuffle():
    global word
    go_btn.pack_forget()

    while word_count < 4:        
        word = random.choice(WORDS)        
        label.config(text=str(word))    
        return

def check(event):
    global word, word_count

    if entry.get().lower() == word.lower():
        update_right()

    elif entry.get().lower() != word.lower():
        update_wrong()

    shuffle()
    entry.delete(0, END)

def update_right():
    global word, word_count

    word_count += 1
    WORDS.remove(word)    
    wrong_label.config(text="")

def update_wrong():
    global word, word_count
    wrong_label.config(text="WRONG!", fg='red')

root = Tk()          
label = Label(root, font=("Helvetica", 60))
wrong_label = Label(root, text="", font =("Helvetica, 14"))                                      

go_btn = Button(root, text="GO!", command=shuffle)
entry = Entry(root)

root.bind("<Return>", check)

label.pack()
wrong_label.pack()
go_btn.pack()
entry.pack()

entry.focus_set()

root.mainloop()

My problem is that even if I retype the word correctly, it is still always wrong. I have checked the text file and there doesn't seem to be anything wrong with. Text file is as follows:

Games
Development
Keyboard
Speed
Typer
Anything
Syndicate
Victory
Inkblot
  • 708
  • 2
  • 8
  • 19

1 Answers1

0

I think the error comes from here:

with open("WORDS_FILE.txt") as f:
    WORDS = list(f.readlines()) #Carriage return is given in each line.

In this part, you read each line of the file and create a list of it, using list constructor. However, each line has a carriage return at the end, when reading from a file. So basically, you want to remove the carriage return by applying .strip('\n') on each string of your list. This could be done naively like this:

Bad way of doing it:

with open("WORDS_FILE.txt") as f:
    WORDS = list(f.readlines()) #Carriage return is given in each line.
for i in range(len(WORDS)): # Iterate over list indexes
    WORDS[i] = WORDS[i].strip('\n') # In place string replacement.

While that does the trick, it does not seem right to iterate over your word list twice (once when reading the file in f.readlines(), and once after when stripping '\n'). There is two solutions for avoiding this:

Solution 1: Explicit file reading iteration:

WORDS = []
with open("WORDS_FILE.txt") as f:
    for line in f:
        WORDS.append(line.strip('\n'))

Solution 2: apply the .strip('\n') function on each item generated by .readlines(), using the function map and a lambda-expression:

with open("WORDS_FILE.txt") as f:
    WORDS = list(map(lambda s: s.strip('\n'), f.readlines()))
DainDwarf
  • 1,651
  • 10
  • 19
  • Thanks I tried using `strip()` on it's own but it wouldn't work, didn't realise I was missing something – Inkblot Dec 16 '15 at 16:27
  • @DwainDwarf I bet your question would be more helpful if you explained how the lambda is working and why it is a better option then just a list comprehension. You have a lot of cool stuff in there but I think a novice would struggle to understand what is going on – PyNEwbie Dec 16 '15 at 16:55
  • @PyNExbie : I've editted much of my answer – DainDwarf Dec 17 '15 at 07:25