G'day,

First of all a very big thank you to both Jeff and Vegaseat for their great help...but sadly :icon_sad: it's not what I needed.

Being a novice at Tkinter I did not realize what Tkinter was and was not capable of and I therefore blame myself :icon_redface: for any of the confusion that came about.

I really don't think that Tkinter can do what I need done. Again I'll try to explain by way of some code I came up with half way through the six months course on Python. After you've run the code I'll try (this time I hope) :icon_rolleyes: to explain in clear language what is needed.

# Copyright M. J. Fenton (alias fredzik) 2007.
#This program is free software; you can redistribute it and/or modify it 
#under the terms of the GNU General Public License as published by the Free 
#Software Foundation; either version 2 of the License, or (at your option) any later version.
#This program is distributed in the hope that it will be useful, but 
#WITHOUT ANY WARRANTY; without even the implied warranty of 
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
#General Public License for more details.
#You should have received a copy of the GNU General Public License 
#along with this program; if not, write to the Free Software Foundation, 
#Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
import random
import time
number1=random.randint(1, 100)
number1a=random.randint(1, 100)
number1b=random.randint(1, 100)
number1c=random.randint(1, 100)
number1d=random.randint(1, 100)
number1e=random.randint(1, 100)
number1f=random.randint(1, 100)
number1g=random.randint(1, 100)
number1h=random.randint(1, 100)
number1i=random.randint(1, 100)
number1j=random.randint(1, 100)
number1k=random.randint(1, 100)
number1l=random.randint(1, 100)
number1m=random.randint(1, 100)
number1n=random.randint(1, 100)
number1o=random.randint(1, 100)
number1p=random.randint(1, 100)
number1q=random.randint(1, 100)
number1r=random.randint(1, 100)
number2=random.randint(1, 100)
number3=random.randint(1, 100)
number3a=random.randint(1, 100)
number3b=random.randint(1, 100)
number3c=random.randint(1, 100)
number3d=random.randint(1, 100)
number3e=random.randint(1, 100)
number3f=random.randint(1, 100)
number3g=random.randint(1, 100)
number3h=random.randint(1, 100)
number3i=random.randint(1, 100)
number3j=random.randint(1, 100)
number3k=random.randint(1, 100)
number3l=random.randint(1, 100)
number3m=random.randint(1, 100)
number3n=random.randint(1, 100)
number3o=random.randint(1, 100)
number3p=random.randint(1, 100)
number3q=random.randint(1, 100)
number3r=random.randint(1, 100)
number4=random.randint(1, 100)
number5=random.randint(1, 100)
number5a=random.randint(1, 100)
number5b=random.randint(1, 100)
number5c=random.randint(1, 100)
number5d=random.randint(1, 100)
number5e=random.randint(1, 100)
number5f=random.randint(1, 100)
number5g=random.randint(1, 100)
number5h=random.randint(1, 100)
number5i=random.randint(1, 100)
number5j=random.randint(1, 100)
number5k=random.randint(1, 100)
number5l=random.randint(1, 100)
number5m=random.randint(1, 100)
number5n=random.randint(1, 100)
number5o=random.randint(1, 100)
number5p=random.randint(1, 100)
number5q=random.randint(1, 100)
number5r=random.randint(1, 100)
number6=random.randint(1, 100)
number7=random.randint(1, 100)
number7a=random.randint(1, 100)
number7b=random.randint(1, 100)
number7c=random.randint(1, 100)
number7d=random.randint(1, 100)
number7e=random.randint(1, 100)
number7f=random.randint(1, 100)
number7g=random.randint(1, 100)
number7h=random.randint(1, 100)
number7i=random.randint(1, 100)
number7j=random.randint(1, 100)
number7k=random.randint(1, 100)
number7l=random.randint(1, 100)
number7m=random.randint(1, 100)
number7n=random.randint(1, 100)
number7o=random.randint(1, 100)
number7p=random.randint(1, 100)
number7q=random.randint(1, 100)
number7r=random.randint(1, 100)
number8=random.randint(1, 100)
number9=random.randint(1, 100)
number9a=random.randint(1, 100)
number9b=random.randint(1, 100)
number9c=random.randint(1, 100)
number9d=random.randint(1, 100)
number9e=random.randint(1, 100)
number9f=random.randint(1, 100)
number9g=random.randint(1, 100)
number9h=random.randint(1, 100)
number9i=random.randint(1, 100)
number9j=random.randint(1, 100)
number9k=random.randint(1, 100)
number9l=random.randint(1, 100)
number9m=random.randint(1, 100)
number9n=random.randint(1, 100)
number9o=random.randint(1, 100)
number9p=random.randint(1, 100)
number9q=random.randint(1, 100)
number9r=random.randint(1, 100)
number10=random.randint(1, 100)
answer1=0
answer2=0
answer3=0
answer4=0
answer5=0
adds=0
run=""
while True:
    words=("***YOU'RE AN ABSOLUTE GENIUS***", "***YOU'RE A BUDDING EINSTEIN***",
           "***HOW DID YOU DO THAT?***", "***SUPERMAN***", "***YOU GENIUS***")
    print "No.1 is %i" % (number1)
    print "No.2 is %i. Now multiply No.1 by No.2" % (number2)
    print
    answer1=number1*number2
    answer1ua=number1a*number1b
    answer1ub=number1c*number1d
    answer1uc=number1e*number1f
    answer1ud=number1g*number1h
    answer1ue=number1i*number1j
    answer1uf=number1k*number1l
    answer1ug=number1m*number1n
    answer1uh=number1o*number1p
    answer1ui=number1q*number1r
    print "**********"
    print answer1 
    print answer1ub
    print answer1ua
    print answer1uc
    print answer1ud
    print answer1ue
    print answer1uf
    print answer1ug
    print answer1uh
    print answer1ui
    print "**********"
    print
    print "WHICH OF THE TEN NUMBERS ABOVE? PUT YOUR ANSWER BELOW."
    answers=int(raw_input('                           Your answer for the 1st is : '))
    print " "
    if answers==answer1:
        print "                                           *****YOU GENIUS*****"
        print "---------------------------------------------------------------"
        print " "
    adds=adds+1
    if answers!=answer1:
        adds=adds-1
        print "                                       WRONG, TRY THE NEXT"
        print "---------------------------------------------------------------"
        print " "
    print "No.3 is %i" % (number3)
    print "No.4 is %i. Now multiply No.3 by No.4" % (number4)
    print
    answer2ua=number3a*number3b
    answer2ub=number3c*number3d
    answer2uc=number3e*number3f
    answer2ud=number3g*number3h
    answer2=number3*number4
    answer2ue=number3i*number3j
    answer2uf=number3k*number3l
    answer2ug=number3m*number3n
    answer2uh=number3o*number3p
    answer2ui=number3q*number3r
    print "**********"
    print answer2ui
    print answer2uh
    print answer2ug
    print answer2uf
    print answer2ue
    print answer2
    print answer2ud
    print answer2uc
    print answer2ub
    print answer2ua
    print "**********"
    print
    print "WHICH OF THE TEN NUMBERS ABOVE? PUT YOUR ANSWER BELOW."
    answers=int(raw_input('                           Your answer for the 2nd is : '))
    print " "
    if answers==answer2:
        print "                                           *****CHAMP*****"
        print "---------------------------------------------------------------"
        print " "
    adds=adds+1
    if answers!=answer2:
        adds=adds-1
        print "                                       WRONG...NEXT ONE"
        print "---------------------------------------------------------------"
        print " "
    print "No.5 is %i" % (number5)
    print "No.6 is %i. Now multiply No.5 by No.6" % (number6)
    print
    answer3=number5*number6
    answer3ua=number5a*number5b
    answer3ub=number5c*number5d
    answer3uc=number1e*number1f
    answer3ud=number1g*number1h
    answer3ue=number1i*number1j
    answer3uf=number1k*number1l
    answer3ug=number1m*number1n
    answer3uh=number1o*number1p
    answer3ui=number1q*number1r
    print "**********"
    print answer3ud
    print answer3ue
    print answer3uf
    print answer3uh
    print answer3ui
    print answer3ug
    print answer3
    print answer3ua
    print answer3ub
    print answer3uc
    print "**********"
    print
    print "WHICH OF THE TEN NUMBERS ABOVE? PUT YOUR ANSWER BELOW."
    answers=int(raw_input('                           Your answer for the 3rd is : '))
    print " "
    if answers==answer3:
        print "                                           *****INCREDIBLE*****"
        print "---------------------------------------------------------------"
        print " "
    adds=adds+1
    if answers!=answer3:
        adds=adds-1
        print "                                       WRONG, NEXT"
        print "---------------------------------------------------------------"
        print " "
    print "No.7 is %i" % (number7)
    print "No.8 is %i. Now multiply No.7 by No.8" % (number8)
    print
    answer4=number7*number8
    answer4ua=number5a*number5b
    answer4ub=number5c*number5d
    answer4uc=number1e*number1f
    answer4ud=number1g*number1h
    answer4ue=number1i*number1j
    answer4uf=number1k*number1l
    answer4ug=number1m*number1n
    answer4uh=number1o*number1p
    answer4ui=number1q*number1r
    print "**********"
    print answer4uh
    print answer4ub
    print answer4ug
    print answer4ui
    print answer4ud
    print answer4ua
    print answer4ue
    print answer4uf
    print answer4
    print answer4uc
    print "**********"
    print
    print "WHICH OF THE TEN NUMBERS ABOVE? PUT YOUR ANSWER BELOW."
    answers=int(raw_input('                           Your answer for the 4th is : '))
    print " "
    if answers==answer4:
        print "                                           *****FANTASTIC*****"
        print "---------------------------------------------------------------"
        print " "
    adds=adds+1
    if answers!=answer4:
        adds=adds-1
        print "                                       NO, NEXT"
        print "---------------------------------------------------------------"
        print " "
    print "No.9 is %i" % (number9)
    print "No.10 is %i. Now multiply No.9 by No.10" % (number10)
    print
    answer5=number9*number10
    answer5ua=number1a*number1b
    answer5ub=number1c*number1d
    answer5uc=number1e*number1f
    answer5ud=number1g*number1h
    answer5ue=number1i*number1j
    answer5uf=number1k*number1l
    answer5ug=number1m*number1n
    answer5uh=number1o*number1p
    answer5ui=number1q*number1r
    print "**********"
    print answer5ug
    print answer5uh
    print answer5ui
    print answer5 
    print answer5uf
    print answer5ue
    print answer5ua
    print answer5ub
    print answer5uc
    print answer5ud
    print "**********"
    print
    print "WHICH OF THE TEN NUMBERS ABOVE? PUT YOUR ANSWER BELOW."
    answers=int(raw_input('                           Your answer for the 5th is : '))
    print " "
    if answers==answer5:
        print "                                           *****MATHEMATICAL GENIUS*****"
        print "---------------------------------------------------------------"
        print " "
    adds=adds+1
    if answers!=answer5:
        adds=adds-1
        print "                                       THE LAST."
        print "---------------------------------------------------------------"
        print " "
    if adds==adds<5:
        import winsound
        import time
        time.sleep(1.5)
        winsound.PlaySound("SystemExit", winsound.SND_ALIAS)
        print " "
        print "***********************"
        print "BETTER LUCK NEXT TIME."
        print "***********************"
        print " "
        print "The first answer was: %i" % (answer1)
        print "The second answer was: %i" % (answer2)
        print "The third was: %i" % (answer3)
        print "The fourth was: %i" % (answer4)
        print "The fifth: %i" % (answer5)
        print "----------------------------------------------"
        run = raw_input("\n'run' again or 'exit' ")
        print
        if run == "exit":
            break
        elif run == "run":
            number1=random.randint(1, 100)
            number2=random.randint(1, 100)
            number3=random.randint(1, 100)
            number4=random.randint(1, 100)
            number5=random.randint(1, 100)
            number6=random.randint(1, 100)
            number7=random.randint(1, 100)
            number8=random.randint(1, 100)
            number9=random.randint(1, 100)
            number10=random.randint(1, 100)
            answer1=0
            answer2=0
            answer3=0
            answer4=0
            answer5=0
            adds=0
            continue
    if adds==adds>4:
        print random.choice(words)
        print " "
        print "                                CONGRATULATIONS, 5 OUT OF 5!!!"
        print " "
        print "The first answer was: %i" % (answer1)
        print "The second answer was: %i" % (answer2)
        print "The third was: %i" % (answer3)
        print "The fourth was: %i" % (answer4)
        print "The fifth: %i" % (answer5)
        print "----------------------------------------------"
        run = raw_input("\n'run' again or 'exit' ")
        print
        if run == "exit":
            break
        elif run == "run":
            number1=random.randint(1, 100)
            number2=random.randint(1, 100)
            number3=random.randint(1, 100)
            number4=random.randint(1, 100)
            number5=random.randint(1, 100)
            number6=random.randint(1, 100)
            number7=random.randint(1, 100)
            number8=random.randint(1, 100)
            number9=random.randint(1, 100)
            number10=random.randint(1, 100)
            answer1=0
            answer2=0
            answer3=0
            answer4=0
            answer5=0
            adds=0
            continue

As you can see the results are spread right across the screen and that's what I need done. In a sense what I need is a second main Idle with the program behaving exactly like it would in the normal main Idle with a scrollable GUI as each game is played. I don't think this can be achieved in Tkinter as it might interfere with the main Idle and as I've found out working with the Python language it tends to hang or freeze when there's a second main GUI around :icon_cry:.

I've tried wxPython (the documentation is a problem) pyQt, venster, pgu, pygame (no scrollbars), easygui, anygui etc. None seem to have the capability to do the job as the main Idle does :icon_sad:.

I wouldn't have persisted with this problem but for the fact that towards the end of my six months training I came up with a game completely different from the one above with about ten times the code length and about one hundred times more interesting which (according to some friends ) shows quite a lot of commercial promise. It may yet see the light of day:icon_wink:.

I am thinking of giving some donations back to the PSF (Python Software Foundation) i.e. giving something back to Python through the sales of games.

Sorry about the length of the post but I think Jeff and Vegaseat deserve a good explanation for the hard work they've done for me.

Whatever happens thanks for your help.

Recommended Answers

All 9 Replies

I don't really understand what you want. You want to run this "game" from Idle _and_ have a Tk-GUI? What should be displayed in the GUI. And why run it from Idle? BTW, do you mean the editor "idle"? I'm just asking because you talk about a "main Idle" and a "second main Idle", whatever this should be.

PS: What you posted is one of the worst codes I've ever seen. You wrote this after a six month training?

G'day,

No, I wrote this about 3 months after I started training...it works perfectly but I just haven't had the time to clean it up hence the no comments etc.

About the Main Idle/second Idle thing. I need the Tkinter GUI or second Idle to act just exactly like the Main Idle with the words and numbers across the screen as it does on the Main Idle.

If you don't understand where I'm coming from please let us know. As it's time for bed here in Oz I'll have to answer any questions tomorrow.

Thanks for your reply.

G'day,

Ok, maybe if I explain it in the following way it might clear things up:

Picture if you will an icon called XYZ sitting on your desktop. If you click on this icon it comes up as the above game with all the words and numbers in exactly the same position as they would be in the Main Python Idle except in a different frame. It would come up the same size as the Main Idle. It only has two dropdown menus on it's upper frame one for saving games and one with a dropdown help widget with help on how to play the game etc. The words and numbers don't have to be in blue they can be in black or any colour. It would be scrollable and you could enter the number/s in it and it would appear onscreen exactly where it does in the Main Idle. The one and only function of this frame (apart from the dropdown menus) would be to play this game.
Can this be done?

Thanks for any help.

Well, Tkinter can certainly do this.

Just a user suggestion, then a coding suggestion, then down to business.

The user has no clue whether he is supposed to enter the index of the answer starting at 1, the index of the answer starting at 0, or the actual answer itself. I tried all three, in that order, and finally caught on. So more precise user directions would be helpful.

I think what sparked the strong reaction in both mawe and me was the fact that you use separate variable names for what are clearly the same type of variable. That's what lists are for. So rather than the above, one could easily write:

answers = [random.randint(1,100) * random.randint(1,100) for x in range(10)]

which has the delightful virtue of eliminating ... let's see here ... approximately 150 lines of code! Yea lists!

In addition, it's good programming practice to divide up your code into functions. In general, no program should have any block that is more than 100 lines long.* Currently, your entire program is in the main block. In reality, your entire main should look something like this:

while True:
    for i in range(total_questions):
        answers = generate_answers()
        print_answers()
        response = get_response()
    try_again = raw_input("Enter 'run' to go again, or 'exit' to exit")
    if try_again != 'run':
        print "bye!"
        break

And that's it! Everything else should be outsourced to your functions, which themselves should do one thing and do it well.

So ... I hope these comments are helpful rather than otherwise. I would strongly suggest, before Tkinter-izing the code, that you refactor it along those lines. I'll post about Tkinter below.

Hope it helps,
Jeff

* With many exceptions to the rule, but none at all for beginners :)

The problem with Tkinter is that it requires thinking differently. Tkinter doesn't go linearly; instead, it responds to events. So setting up the GUI is a static thing (for simple apps): you create the frame. THEN, you make the frame respond to user input.

So a simple frame might look like this:

import Tkinter as tk

class MyFrame(tk.Frame):

    def __init__(self,parent):
        tk.Frame.__init__(self, parent)
        self.label = tk.Label(self,text="Multiplication Skillz Test0r")
        self.label.grid()
        self.answers = tk.StringVar()
        self.answers.set("\n"*10)
        self.answer_label = tk.Label(self,textvariable=self.answers)
        self.answer_label.grid()
        self.response = tk.Entry(self)
        self.response.grid()

mainw = tk.Tk()
mainw.frame = MyFrame(mainw)
mainw.frame.grid()
mainw.mainloop()

Now, this is (intentionally :P) a very raw skeleton that you should remake as needed.

From there, you will use Bind to make the GUI responsive: When the user presses <Enter>, the mainw.frame.response widget needs to call its callback to determine if the answer is correct, if another problem needs to be shown, or if the game is over.

Hope that gets you in the right direction,
Jeff

Very good posts, jrcagle! I see that yours are much more useful than mine, and, much more polite :) I think I have to say sorry to fredzik.

PS: I _hate_ the new smilies!!! :@

G'day,

This time I won't say "I'm sure this will work":icon_redface:. Being a novice at Tkinter I didn't have the correct terminology to explain exactly what I needed done:icon_redface:. This'll be a problem that'll come up from time to time when some beginners struggle to find the right terms in which to express what they need done. If it wasn't for the patience of blokes like Jeff, Vegaseat, and yes, you to Mawe (it's ok) then beginners like us may in fact give up on the language which (I admit) at times I've been tempted to do when the solution to a problem was not immediately obvious.

Python is a great language and if it wasn't for the likes of blokes like these, and others I may yet come across, that work tirelessly and without pay to help the struggling ones like myself then Python itself might die and that would be the greatest shame of all because I can't think of a better language that deserves success more than this one. This is just a word of thanks on behalf of all those that you've helped so far:icon_smile:.

P.S. I agree with Mawe I like the old smilies to.

fredzik

G'day again,

The above code was never intended to be used publicly. After about three months of beginning Python I decided to invent a game (the above code) just to test my own coding abilities and never planned for it to be used anywhere, hence the no comments etc.

The only reason I emailed the code was that the game's final screen output (words and numbers etc going across the screen) is somewhat similar to the commercial game (here's hoping:icon_wink: ) that I'm currently working on (the actual game code itself is finished). The reason that I need the scrollbar is that it's sort of like a detective game where any previous input and output can checked on by scrolling back to the earlier output given as there are certain clues given which don't make sense at all when given but when scrolled back later suddenly do make sense. Therefore the scrollbar is absolutely essential to finding the answers to the puzzle.

And lastly to Mawe if you still like the old smilies the next time you post and want to use one of the old smilies just go to the [more] tab and scroll down they are still there!:icon_cheesygrin: :icon_cheesygrin: :icon_cheesygrin:

fredzik

G'day,

I've just posted again to ask permission from Vegaseat to use the "Simple Calculator" that I found in one of his earlier posts in my game.

# a tiny/simple Tkinter calculator (improved v.1.1)
# if you enter a number with a leading zero it will be an octal number!
# eg. 012 would be a decimal 10  (0.12 will not be affected)
# used a more modern import to give Tkinter items a namespace
# tested with Python24     vegaseat     08dec2006
"""
calculator has a layout like this ...
<   display   >
7  8  9    
4  5  6    
1  2  3  
0  C  =  
"""
import Tkinter as tk
def click(key):
    global memory
    if key == '=':
        # guard against the bad guys abusing eval()
        str1 = "0123456789."
        if entry.get()[0] not in str1:
            entry.insert(tk.END, "first char not in " + str1)
        # here comes the calculation part
        try:
            result = eval(entry.get())
            entry.insert(tk.END, " = " + str(result))
        except:
            entry.insert(tk.END, "--> Error!")
    elif key == 'C':
        entry.delete(0, tk.END)  # clear entry
        if '=' in entry.get():
            entry.delete(0, tk.END)
    else:
        # previous calculation has been done, clear entry
        if '=' in entry.get():
            entry.delete(0, tk.END)
        entry.insert(tk.END, key)
root = tk.Tk()
root.title("Simple Calculator")
btn_list = [
'7',  '8',  '9',  
'4',  '5',  '6',  
'1',  '2',  '3',  
'0',  'C',  '=',]
# create all buttons with a loop
r = 1
c = 0
for b in btn_list:
    rel = 'ridge'
    cmd = lambda x=b: click(x)
    tk.Button(root,text=b,width=5,relief=rel,command=cmd).grid(row=r,column=c)
    c += 1
    if c > 4:
        c = 0
        r += 1
# use Entry widget for an editable display
entry = tk.Entry(root, width=33, bg="yellow")
entry.grid(row=0, column=0, columnspan=5)
root.mainloop()

I changed the code around a bit...NAY, I DESTROYED IT WITH GREAT DELIGHT:icon_twisted: :icon_twisted: :icon_twisted: laughing all the way as I did it!!! Um, sorry...er, I don't know what came over me...anyway, this took as much as half an hour to do, whereas you guys would probably only take about 2 minutes. I'm afraid I'm as slow as a wet rag at Tkinter:icon_cry: and at this rate it'll probably take me about 400 years just to finish the GUI (that is if the wind blows in the right direction)...anyway, I hope it's ok with you Vegaseat that I use it...

From the Calculator Killer

fredzik

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.