layout_window is not defined even if i defined it - python

I did a game from a coding book in python and it says layout_window is not defined even if i wrote
def layout_window(window):
here is my code
import tkinter
import random
gameOver = False
score = 0
squaresToClear = 0
def play_bombdodger():
create_bombfield(bombfield)
window = tkinter.Tk()
layout_window(window)
window.mainloop
bombfield = []
def create_bombfield(bombfield):
global squaresToClear
for row in range(0,10):
rowList = []
for column in range(0,10):
if random.randint(1,100) < 20:
rowList.append(1)
else:
rowList.append(0)
squaresToClear = squaresToClear + 1
bombfield.append(rowList)
printfield(bombfield)
def printfield(bombfield):
for rowList in bombfield:
print(rowList)
play_bombdodger()
def layout_window(window):
for rowNumber, rowList in enumerate(bombfield):
for columnNumber, columnEntry in enumerate(bombfield):
if random.randint(1,100) < 25:
square = tkinter.Label(window, text = " ", bg = "darkgreen")

You call play_bombdodger which calls layout_window, but you call play_bombdodget before you define layout_window.

Related

I am trying to make guessing game in Python Tkinter. But I don't get the result I what. what's the problem?

here's the code:
from tkinter import *
import random
win = Tk()
win.geometry("500x500")
win.title('Guessing Game')
TARGET = random.randint(1,5)
guess = IntVar()
output = 'hello'
def play_game():
global guess
global output
if guess.get() > TARGET:
output = 'too high'
elif TARGET > guess.get():
output = 'too low'
elif TARGET == guess.get():
output = 'Right guess'
title = Label(win,text='Guessing Game').place(anchor=CENTER,x=250,y=100)
title1 = Label(win,text='number from 1 - 5',height=10).place(anchor=CENTER,x=250,y=150)
entry = Entry(win,textvariable=guess).place(anchor=CENTER,x=250,y=200)
click = Button(win,text='Guess',command=play_game).place(anchor=CENTER,x=250,y=250)
ans = Label(win,text=TARGET).place(anchor=CENTER,x=250,y=300)
ans1 = Label(win,text=output).place(anchor=CENTER,x=250,y=350)
win.mainloop()
I wanted to change ans1 text but it doesn't. I hope you understand what I am asking.
You need this ans.configure. And put this in line 21.
In line 29, removed parameter `text=TARGET
In line 29 split two line instead of one line to prevent an error.
Code:
from tkinter import *
import random
win = Tk()
win.geometry("500x500")
win.title('Guessing Game')
TARGET = random.randint(1,5)
guess = IntVar()
output = 'hello'
def play_game():
global guess
global output
if guess.get() > TARGET:
output = 'too high'
elif TARGET > guess.get():
output = 'too low'
elif TARGET == guess.get():
output = 'Right guess'
ans.configure(text=output)
title = Label(win,text='Guessing Game').place(anchor=CENTER,x=250,y=100)
title1 = Label(win,text='number from 1 - 5',height=10).place(anchor=CENTER,x=250,y=150)
entry = Entry(win,textvariable=guess).place(anchor=CENTER,x=250,y=200)
click = Button(win,text='Guess',command=play_game).place(anchor=CENTER,x=250,y=250)
ans = Label(win)
ans.place(anchor=CENTER,x=250,y=300)
ans1 = Label(win,text=output).place(anchor=CENTER,x=250,y=350)
win.mainloop()
Screenshot:
Screenshot:
screenshot:

trying to compare two lists or one list with the same

import random
b=[]
o=[]
v=0
g=2
y=0
V=0
q=0
compat=0
alex=[]
zach=[]
while v != 5:
name="name"
position="position"
answers=[]
for i in range(10):
answer=random.randint(1,4)
answers.append(answer)
b.append(name)
b.append(position)
b.append(answers)
v+=1
print(b)
for ii in range(0,5):
t=b[g]
o.append(t)
g+=3
l=len(o)
for iii in list(o):
C = o[y]
y = y + 1
alex = []
for iiii in range(5):
I = 0
compat=0
R=o[q]
V=0
Y = C[V]
for iiiii in range(10):
r=R[I]
if r == Y:
compat+=1
else:
compat=compat
I+=1
V += 1
print(compat)
alex.append(compat)
print(alex)
zach.append(alex)
q+=1
w=len(zach)
print(zach)
print(w)
this is my code and it works pretty well. but it should put every single value against every other one but it doesnt it just put the same Y value and does not change. i have put v+=1 in tons of different places and moved around the a couple variable but it doesnt change. there should be 25 different answers for 5 people but it doesnt it just prints the same number 5 times then restarts.
any help would be appreciared
Edit: this is what i will intergrat the code above into
global compatability
import sqlite3
with sqlite3.connect("Questionare.db") as db:
cursor = db.cursor()
class mentee: # these classes are made to create a place where atributes can be filled with variables
def __init__(self,mentee_name,mentee_position):
self._mentee_posisition=mentee_position
self._mentee_name=mentee_name
def menteereport(self):
return{"mentee name:":self._mentee_name,"mentee position":self._mentee_posisition}
class mentor:
def __init__(self,mentor_name,mentor_position):
self._mentor_position=mentor_position
self._mentor_name=mentor_name
def mentorreport(self): # these are methods and they use a function with the variables instanciated within the class to make this appen
return {"mentor name":self._mentor_name,"mentor position":self._mentor_position}
class calculation:
def __init__(self,number_of_questions,compatability,mentoranswers,menteeanwers):
self._question_number= 1
self._number_of_questions=number_of_questions
self._compatability=compatability
self._mentor_values=mentoranswers
self._mentee_values=menteeanwers
def calc(self):
compat=0
c=0
for i in range(0,self._number_of_questions):
if self._mentee_values[c] == self._mentor_answers[c]:
compat += 1
c+=1
else:
compat += 0
c+=0
compatability=compat/self._number_of_questions
self._compatability=compatability
compatability=compatability*100
print(self._mentee_answers)
print(self._mentor_answers)
print("\n{:0.2f}%.\n".format(compatability))
def mentoranswer(self):
self._number_of_questions = int(self._number_of_questions)
self._question_number=1
for i in range(0,self._number_of_questions):
answer=input("Q{}".format(self._question_number))
self._question_number+=1
self._mentor_answers.append(answer)
def menteeanswer(self):
self._number_of_questions = int(self._number_of_questions)
self._question_number=1
for i in range(0,self._number_of_questions):
answer=input("Q{}".format(self._question_number))
self._question_number+=1
self._mentee_answers.append(answer)
class timerequirements:
def __init__(self,mentor_time_allotment,mentee_time_allotment,ideal_length_of_mentoring,ideal_length_of_being_mentored):
self._mentor_time_allotment=mentor_time_allotment
self._mentee_time_allotment=mentee_time_allotment
self._ideal_length_of_mentoring=ideal_length_of_mentoring
self._ideal_length_of_being_mentored=ideal_length_of_being_mentored
def main(): # this function is created to put the variables into the artibutes so that everything will work.
v = True
mentoranswers = []
menteeanswers = []
no_of_q = int(input("numebr of questions"))
while v == True:
morm = input("are your a mentor or a mentee")
if morm.lower() == "mentor":
name = input("name")
position = input("position")
answers = []
for i in range(0, no_of_q):
answer = int(input("1 or 2"))
answers.append(answer)
mentoranswers.append(name)
mentoranswers.append(position)
mentoranswers.append(answers)
print(mentoranswers)
elif morm.lower() == "mentee":
name = input("name")
position = input("position")
answers = []
for i in range(0, no_of_q):
answer = int(input("1 or 2"))
answers.append(answer)
menteeanswers.append(name)
mentoranswers.append(position)
menteeanswers.append(answers)
print(menteeanswers)
elif morm.lower() == "q":
v = False
else:
print("try again")
print(mentoranswers.mentorreport())
print(menteeanswers.menteereport())
main()
you are adding way too much noise.
for iii in list(o):
C = o[y]
y = y + 1
why don't you simply use the variable you just created? it will be incremented automatically
for iii in list(o):
C = o[iii]
you should learn how to use a loop and a few other basics. there are good tutorials on the official python site. here the for-loop one. most of your variables exist just to repeat what you are already doing.
i've avoided some high-level constructs, but i left zip.
import random
mentees = []
names = ['zach', 'alex', 'fred', 'jane', 'sara']
for name in names:
mentee = dict()
mentee['name'] = name
mentee['compatibility'] = []
answers = []
for i in range(10):
answers.append(random.randint(1,4))
mentee['answers'] = answers
mentees.append(mentee)
for mentee1 in mentees:
m1_answers = mentee1['answers']
for mentee2 in mentees:
m2_answers = mentee2['answers']
compat = 0
# zip fuses both lists into one
for m1_answer, m2_answer in zip(m1_answers, m2_answers):
if m1_answer == m2_answer:
compat += 1
mentee1['compatibility'].append((mentee2['name'], compat))
print(mentees)

Python find closest turtle via mouse click

I'm in the process of creating a minesweeper style game using a turtle-based grid setup. I need to find the closest cell within the grid and reveal the icon located under it whether that be a bomb or a number icons. I'm not looking to make it exact, I just need the mouse click to find the nearest cell in the grid even if the click isn't directly on the board. Currently my code only reveals the icon of the last turtle created on the board and then does nothing else with further clicks.
What can I do to make it recognize the real closest click and do it multiple times until the last bomb is found?
import random
import turtle
import cell
class Game:
def __init__(self, size):
registershapes()
self.__boardsize = size
self.__boardlist = []
self.__bombnum = 0
self.__probe = 0
self.__probelist = []
offset = (size-1) * 17
for x in range(size):
for y in range(size):
t = cell.Cell(x,y)
t.up()
t.shape('question.gif')
t.goto(y*34-offset, offset-x*34)
self.__boardlist.append(t)
def hideMines(self, num):
if num > self.__boardsize ** 2:
return False
self.__bombnum = num
self.__rnums = []
i = 0
while i < self.__bombnum:
currentnum = random.randrange(0, (self.__boardsize**2) - 1)
if currentnum not in self.__rnums:
self.__rnums.append(currentnum)
i += 1
return True
def probe(self, x, y):
for t in self.__boardlist:
pos = t.position()
distx = abs(x - pos[0])
disty = abs(y - pos[1])
distfinal = (distx ** 2 + disty ** 2) ** 0.5
curdist = 0
if curdist < distfinal:
curdist = distfinal
closest = t
if closest in self.__probelist:
return (self.__probe, self.__bombnum)
elif closest in self.__rnums:
closest.shape("bomb.gif")
self.__bombnum -= 1
self.__probe += 1
self.__probelist.append(closest)
return (self.__probe, self.__bombnum)
else:
closest.shape("0.gif")
self.__probe += 1
self.__probelist.append(closest)
return (self.__probe, self.__bombnum)
def registershapes():
wn = turtle.Screen()
wn.register_shape('0.gif')
wn.register_shape('1.gif')
wn.register_shape('2.gif')
wn.register_shape('3.gif')
wn.register_shape('4.gif')
wn.register_shape('5.gif')
wn.register_shape('6.gif')
wn.register_shape('7.gif')
wn.register_shape('8.gif')
wn.register_shape('9.gif')
wn.register_shape('bomb.gif')
wn.register_shape('question.gif')
I believe you're approaching this problem the wrong way. You're activating screen.onclick() and trying to map it to a turtle. Instead, activate turtle.onclick() on the individual turtles, deactivating it when a turtle is selected. Then you don't have to search for the turtle in question, and not actively ignore turtles that have already been selected.
Below is my rework of your code from this and your previous question into an example you can run. I had to guess about the definition of the Cell class:
from turtle import Turtle, Screen
import random
class Cell(Turtle):
def __init__(self, number):
super().__init__("question.gif")
self.__number = number
self.penup()
def number(self):
return self.__number
class Game:
def __init__(self, size):
registershapes()
self.__boardsize = size
self.__boardlist = []
self.__bombnum = 0
self.__probe = 0
self.__rnums = None
offset = (size - 1) * 17
for y in range(size):
for x in range(size):
t = Cell(x + y * size)
t.goto(x * 34 - offset, offset - y * 34)
t.onclick(lambda x, y, self=t: closure(self))
self.__boardlist.append(t)
def hideMines(self, num):
if num > self.__boardsize ** 2:
return False
self.__bombnum = num
self.__rnums = []
i = 0
while i < self.__bombnum:
currentnum = random.randrange(0, self.__boardsize ** 2 - 1)
if currentnum not in self.__rnums:
self.__rnums.append(currentnum)
i += 1
return True
def probe(self, closest):
closest.onclick(None)
if closest.number() in self.__rnums:
closest.shape("bomb.gif")
self.__bombnum -= 1
else:
closest.shape("0.gif")
self.__probe += 1
return (self.__probe, self.__bombnum)
def registershapes():
screen.register_shape('0.gif')
# ...
screen.register_shape('bomb.gif')
screen.register_shape('question.gif')
def closure(closest):
_, rem = mine.probe(closest)
if rem == 0:
over = screen.textinput("Text Input", "Would you like to play again? (Y)es or (N)o")
if over.upper() == 'Y':
main()
else:
screen.bye()
def main():
global mine
board = screen.numinput("Numeric Input", "Enter desired board size: ")
mine = Game(int(board))
nummine = screen.numinput("Numeric Input", "Enter desired number of mines: ")
mine.hideMines(int(nummine))
screen = Screen()
mine = None
main()
screen.mainloop()

What would be the best way to update my boolean using tkinter buttons?

I am working on a calculator and I want it so once the user is done entering the first number and chooses an operator(+-*/ etc.) they can enter a second number and then hit an equals button to get their answer.
Currently, I can not assign a value to my bool inside my defs, which is keeping me from being able to input a second number and eventually perform functions. The last line of commandButtonPress() is where things are slipping up, and prior to making whichNum a list I was getting:
variable referenced before assignment
I have tried both direct assignment as well as using remove() and append(). Buttons 1-9 use the same block of code, and I didn't include the decimal because I didn't think it would be necessary for solving this problem.
I know none of this is elegant and most of it would be far better if I implemented a class, but I am new and trying to figure things out and haven't done object oriented programming in python yet.
from tkinter import *
def buttonOne(whichNum):
count = 0
number = ""
try:
if whichNum == False and num1[0] != "0":
num1.append("1")
while count < len(num1):
number = number + str(num1[count])
count += 1
screen["text"] = number
elif whichNum == True and num2[0] != "0":
num2.append("1")
while count < len(num2):
number = number + str(num2[count])
count += 1
screen["text"] = number
except:
if whichNum == False:
num1[0] = "."
else:
num2[0] = "."
number = "0."
screen["text"] = number
def commandButtonPress(symbol, whichNum):
if whichNum == False:
if len(operator) > 0 and operator[0] == "+":
operator.remove("+")
if len(num1) > 0:
operator.append(symbol)
whichNum[0] = True
def main():
window = Tk()
window.title("Calculator")
window.geometry("250x305")
num1 = []
num2 = []
operator = []
whichNum = [False]
global screen
screen = Label(text="0", height = 5, width = 30)
screen.pack(side = LEFT, expand=False, anchor = N, padx=[5, 5])
button1 = Button(text="1", command = lambda: buttonOne(whichNum[0]))
button1.grid(column=0, row=2)
button11 = Button(text="+", command = lambda: commandButtonPress("+", whichNum[0]))
button11.grid(column=3, row=2)
window.mainloop()
main()
The solution Nae posted seems to work. My button doesn't handle num2 properly yet, but whichNum is getting updated as it should in commandButtonPress. Thanks for the help. I finished this project (more or less) and uploaded it to my repo.
from tkinter import *
whichNum = False
def buttonOne():
global whichNum
count = 0
number = ""
try:
if whichNum == False and num1[0] != "0":
num1.append("1")
while count < len(num1):
number = number + str(num1[count])
count += 1
screen["text"] = number
elif whichNum == True and num2[0] != "0":
num2.append("1")
while count < len(num2):
number = number + str(num2[count])
count += 1
screen["text"] = number
except:
if whichNum == False:
num1[0] = "."
else:
num2[0] = "."
number = "0."
screen["text"] = number
def commandButtonPress(symbol):
global whichNum
if whichNum == False:
if len(operator) > 0 and operator[0] == "+":
operator.remove("+")
if len(num1) > 0:
operator.append(symbol)
whichNum[0] = True
def main():
window = Tk()
window.title("Calculator")
window.geometry("250x305")
num1 = []
num2 = []
operator = []
global whichNum
global screen
screen = Label(text="0", height = 5, width = 30)
screen.pack(side = LEFT, expand=False, anchor = N, padx=[5, 5])
button1 = Button(text="1", command = lambda: buttonOne())
button1.grid(column=0, row=2)
button11 = Button(text="+", command = lambda: commandButtonPress("+"))
button11.grid(column=3, row=2)
window.mainloop()
main()

Trouble with global dictionary

import tkinter as tk
#messagebox is not imported automatically w/ tkinter
from tkinter import messagebox as tkMessageBox
from tkinter import ttk
from random import random as rand
class Square(object):
""" class to use for each square """
def __init__(self):
self.mine_yn = False
self.flag_yn = False
self.prox_num = 0 # number of nearby mines, parse_mines() will fill this in.
self.button = None # ttk.Button instance.
def parse_mines():
"""Look at how many mines are next to a given square,
store in each Square instance that is inside of sqr_dict. """
global sqr_dict
global mine_frame
print('in parse_mines, sqr_dict='+str(sqr_dict))
def try_a_square(sq): #sq = coordinate string(key)
try:
if sqr_dict[sq].mine_yn == True: return 1
if sqr_dict[sq].mine_yn == False: return 0
except KeyError:
print('KeyError for '+sq)
return 0
n = 0
for x in range(5):
for y in range(4):
#check the 8 adjacent squares.
n = n + try_a_square('x'+str(x+1)+'y'+str(y+1))
n = n + try_a_square('x'+str(x+1)+'y'+str(y ))
n = n + try_a_square('x'+str(x+1)+'y'+str(y-1))
n = n + try_a_square('x'+str(x )+'y'+str(y+1))
n = n + try_a_square('x'+str(x )+'y'+str(y-1))
n = n + try_a_square('x'+str(x-1)+'y'+str(y+1))
n = n + try_a_square('x'+str(x-1)+'y'+str(y ))
n = n + try_a_square('x'+str(x-1)+'y'+str(y-1))
if sqr_dict[('x'+str(x)+'y'+str(y))].mine_yn == False:
(sqr_dict[('x'+str(x)+'y'+str(y))]).prox_num = n
print('x'+str(x)+'y'+str(y)+': '+str(n)) #(debug) print n for each sq
#sqr_dict[('x'+str(x)+'y'+str(y))].button.text=(str(n)) #(debug) show n on each button.
n = 0
def create_mine_field():
global mine_frame
global sqr_dict
sqr_dict = {}
mine_frame = tk.Toplevel(root)
mine_frame.grid()
#what to do if user hit 'X' to close window.
mine_frame.protocol("WM_DELETE_WINDOW", mine_frame_close)
# create grid of squares (buttons)
for x in range(5):
for y in range(4):
coord = 'x'+str(x) + 'y'+str(y)
sqr_dict[coord] = Square()
#print('coord='+coord) #debug
#populate with mines
if ( rand()*100 < mines_pct ):
sqr_dict[coord].mine_yn = True
print(str(sqr_dict[coord].mine_yn))
else:
sqr_dict[coord].mine_yn = False
if sqr_dict[coord].mine_yn:
t = '*'
else: t = ' '
# draw boxes
sqr_dict[coord].button = ttk.Button(mine_frame, text=t, width=3 )
sqr_dict[coord].button.grid(column=x, row=y)
# done, next: parse!
print('in create_mines, sqr_dict='+str(sqr_dict))
#parse_mines()
def root_close():
root.destroy()
def mine_frame_close():
root.destroy()
root = tk.Tk()
root.title("MineSweeper")
mines_pct = 20
start_button = ttk.Button(root,text="Start",command=create_mine_field)
start_button.pack()
root.mainloop()
I'm trying to make a simple minesweeper game with tkinter. If I run the above code a simple mine field appears. However if I uncomment the call to parser() then nothing shows up and it seems like it never finds any mines in the sqr_dict dictionary. (parser() will fill in the numbers of adjacent mines for each square)
I don't understand why this function would cause trouble before it is even called. No mine field appears when it's called. Please kindly give me your suggestions. Thanks!
The reason nothing shows up is because you are using both pack and grid on widgets that are children of the root window. Within any given window you must only use one or the other.

Categories