0

I'm currently making a hangman game for my school project and have hit a snag. I'm trying to test my code and see if I can make it output yay in the console if the character you press on the GUI is correct, and output boo if not. I've tried a try, except and an if else, and the if else says that 'text' is not defined. (Sorry about the block with the buttons, I'm going to clean that up soon!!!) Here's the code:

#Hangman

from tkinter import *
import random

root = Tk()


word_list = ["APPLE", "PEAR", "BANNANA"]

word = word_list [random.randrange(0,2)]

#Functions
def click_1 ():
    if text in word == true:
        print ("yay")
    else:
        print ("Boo")



#Frames
hangman_frame = Frame(root).grid(row=0, column=0)
letter_frame = Frame(root).grid(row=1, column=0)

#Buttons
A = Button(letter_frame, text="A", command=click_1).grid(row=0, column=0, sticky=W)
B = Button(letter_frame, text="B", command=click_1).grid(row=0, column=1, sticky=W)
C = Button(letter_frame, text="C", command=click_1).grid(row=0, column=2, sticky=W)
D = Button(letter_frame, text="D", command=click_1).grid(row=0, column=3, sticky=W)
E = Button(letter_frame, text="E", command=click_1).grid(row=0, column=4, sticky=W)
F = Button(letter_frame, text="F", command=click_1).grid(row=0, column=5, sticky=W)
G = Button(letter_frame, text="G", command=click_1).grid(row=0, column=6, sticky=W)
H = Button(letter_frame, text="H", command=click_1).grid(row=0, column=7, sticky=W)
I = Button(letter_frame, text="I", command=click_1).grid(row=0, column=8, sticky=W)
J = Button(letter_frame, text="J", command=click_1).grid(row=0, column=9, sticky=W)
K = Button(letter_frame, text="K", command=click_1).grid(row=0, column=10, sticky=W)
L = Button(letter_frame, text="L", command=click_1).grid(row=0, column=11, sticky=W)
M = Button(letter_frame, text="M", command=click_1).grid(row=0, column=12, sticky=W)
N = Button(letter_frame, text="N", command=click_1).grid(row=1, column=0, sticky=W)
O = Button(letter_frame, text="O", command=click_1).grid(row=1, column=1, sticky=W)
P = Button(letter_frame, text="P", command=click_1).grid(row=1, column=2, sticky=W)
Q = Button(letter_frame, text="Q", command=click_1).grid(row=1, column=3, sticky=W)
R = Button(letter_frame, text="R", command=click_1).grid(row=1, column=4, sticky=W)
S = Button(letter_frame, text="S", command=click_1).grid(row=1, column=5, sticky=W)
T = Button(letter_frame, text="T", command=click_1).grid(row=1, column=6, sticky=W)
U = Button(letter_frame, text="U", command=click_1).grid(row=1, column=7, sticky=W)
V = Button(letter_frame, text="V", command=click_1).grid(row=1, column=8, sticky=W)
W = Button(letter_frame, text="W", command=click_1).grid(row=1, column=9, sticky=W)
X = Button(letter_frame, text="X", command=click_1).grid(row=1, column=10, sticky=W)
Y = Button(letter_frame, text="Y", command=click_1).grid(row=1, column=11, sticky=W)
Z = Button(letter_frame, text="Z", command=click_1).grid(row=1, column=12, sticky=W)
18166
  • 111
  • 1
  • 13
  • I have no idea what this code is supposed to do. I run it and nothing happens. Don't see any errors except I had to capitalize Tkinter. – Fred S Dec 23 '14 at 19:54
  • @Fred S It opens a gui with all the buttons and when you click a button I wanted it to say yay if it is in one of the words (pear bannana etc.) and boo if its not. – 18166 Dec 23 '14 at 19:56
  • OK. Now I see. The trouble is that you are not getting the text from the button as "text". You would have to pass the text into the function. I will try to make an answer. – Fred S Dec 23 '14 at 20:07
  • Ok word of advice. Try elementary command line based simple programs first, when you are just getting into learning a language. If you jump into GUI programming like this, there's a lot of information and concepts thrown at you. – kartikg3 Dec 23 '14 at 20:17
  • I've just recently taken a break from python and learned c# so no thanks. Thanks for being so nice though. 10/10 would recommend. @kartikg3 – 18166 Dec 23 '14 at 20:18

4 Answers4

2

I fixed a few syntax issues, and have the buttons generated in a loop. Let me know if this works for you.

#Hangman

from tkinter import *
import random, functools, string

root = Tk()

word_list = ["APPLE", "PEAR", "BANNANA"]

word = word_list [random.randrange(0,2)]

#Functions
def click_1 (text):
    if text in word:
        print ("yay")
    else:
        print ("Boo")

#Frames
hangman_frame = Frame(root).grid(row=0, column=0)
letter_frame = Frame(root).grid(row=1, column=0)

#Buttons
r = c = 0
for letter in string.ascii_uppercase:
    Button(letter_frame, text=letter, command=functools.partial(click_1, letter)).grid(row=r, column=c, sticky=W)
    c += 1
    if c > 12:
        c = 0
        r += 1
Fred S
  • 985
  • 4
  • 11
  • Thanks for making my buttons into a loop - I kinda know how to do this, but it would take me ages and you saved me a lot of work. I'm now going to annotate all the code and see if I understand it, then try and rewrite it! What were the syntax issues may I ask? – 18166 Dec 23 '14 at 20:24
  • "if text in word == true:" and "from tkinter import *". These were pointed out by others I think. – Fred S Dec 23 '14 at 21:19
  • @fred s the tkinter is ok. The module has been renamed to tkinter in python 3. He is probably using python 3. In versions < python 3 tkinter used to be Tkinter. – kartikg3 Dec 23 '14 at 21:26
  • I tested on 2.7. My bad. Thanks for the info, I will update my answer. – Fred S Dec 23 '14 at 21:46
1

The issue you have can be solved using this thread:

How to pass arguments to a Button command in Tkinter?

The solution is to pass the text argument when you call "click_1" function using the "command" field of the button like so:

  button = Tk.Button(master=frame, text='A', command= lambda: click_1("A"))
Community
  • 1
  • 1
raw-bin hood
  • 5,839
  • 6
  • 31
  • 45
0

It's bad practice to test a boolean in that fashion ( == true) (also, you should capitalize "True" :)

You want to try something more like

if (text in word):
hdizzle
  • 41
  • 4
  • 1
    May I ask why? I see people say its bad practise to do such and such, but I never understand why. It works on some of those things (like having Button().grid() instead of Button() \n varName.grid()) – 18166 Dec 23 '14 at 20:15
  • "== true" will fail with a syntax error, since it thinks "true" is a variable which does not exist. – Fred S Dec 23 '14 at 20:18
  • @18166 The "if" statement evaluates the statement and checks for "truthness" already (internally). Adding " == True" is redundant. It also precludes you from using other "falsy" values. – Keith Dec 23 '14 at 22:27
0

I know you got your answer, but just thought I'd put this one out there. I borrowed @Fred S' code and wrote this:

#Hangman
from tkinter import *
import random, functools, string


class HangmanGameFrame(Frame):
    def __init__(self,
                 parent=None,
                 word_list=("APPLE", "PEAR", "BANNANA")):
        super(HangmanGameFrame, self).__init__()
        self.word_list = word_list
        self.word = self.word_list[random.randrange(0,len(word_list))]
        self.create_ui()

    def create_ui(self):
        #Frames
        self.hangman_frame = Frame(root).grid(row=0, column=0)
        self.letter_frame = Frame(root).grid(row=1, column=0)

        def create_buttons():
            #Buttons
            r = c = 0
            for letter in string.ascii_uppercase:
                Button(self.letter_frame, text=letter, command=functools.partial(self.letter_click_handler, letter)).grid(row=r, column=c, sticky=W)
                c += 1
                if c > 12:
                    c = 0
                    r += 1
        create_buttons()            

    def configure(self, *args, **kwargs):
        if kwargs['word_list']:
            self.set_word_list(kwargs['word_list'])
            kwargs.pop('word_list', None)
        super().configure(*args, **kwargs)

    def set_word_list(self, word_list):
        self.word_list = word_list
        self.word = self.word_list[random.randrange(0,len(word_list))]

    def letter_click_handler(self, text):
        if text in self.word:
            print ("yay")
        else:
            print ("Boo")


if __name__ == "__main__":
    root = Tk()
    hangman_frame = HangmanGameFrame(parent=root)
    hangman_frame.configure(word_list=["ZEBRA"]) 
    root.mainloop()

All I did was just refactor the code to make it cleaner. GUI programming is always better when it is done using an object oriented approach IMO. It makes your code easier to extend and maintain. This is just a few of the things I edited from your original code. Please go through it and see if you can compare and get some pointers. I am sure your teacher would appreciate better structure. Hope this helps out.

P.s. If you already knew these concepts, then good for you, and just some practice for me. Cheers.

kartikg3
  • 2,590
  • 1
  • 16
  • 23