[Tutor] Crossword program

David Holland davholla2002 at yahoo.co.uk
Wed Jan 12 14:43:55 CET 2005


Thanks Alan for that suggestion.  I will try and tidy it up myself and then ask the tutor list for another suggestions.

Alan Gauld <alan.gauld at freenet.co.uk> wrote:Hi David,

Its probably the kind of thing you could put on the
Useless Python website. Useless is a collection of
not-too-serious software written in Python which,
despite the name, is actually quite useful for beginners
to download and look at and learn. They can try
improving it, or using the ideas for their own
programs.

But you might well get some suggestions on tidying
it up a little first...

Alan G.

----- Original Message ----- 
From: "David Holland" 
To: 
Sent: Sunday, January 09, 2005 9:44 PM
Subject: [Tutor] Crossword program


> I wrote a program to create crosswords in python.
> It is not perfect but it works, is there any open
> source place I can put this for it to be used by
> anyone who wants it ? (Subject to the gpl licence).
> Here is the code in case anyone is interested.
>
> from Tkinter import *
> #Crossword program David Holland
> class Crossword(Frame):
>
> def __init__(self, master):
> '''Default arguments'''
> Frame.__init__(self, master)
> self.grid()
> self.create_widgets()
> NUM_SQUARES = 169
> EMPTY = " "
> global questionanswer
> questionanswer = {}
> global dictshort
> dictshort = {}
>
> def readdict(self):
> #get the dictionary from a file
> try:
> pickle_file = open(dictfile, "rb")
> dictread = cPickle.load(pickle_file)
> except:
> dictread = {}
> return dictread
>
> def writedict(self, dictent):
> #write dictionary to file
> pickle_file = open(dictfile, "wb")
> cPickle.dump(dictent, pickle_file)
> pickle_file.close()
>
> def showclues(self):
> #show clues on the screen
> questionanswer = self.readdict()
> textent = self.showinfo(questionanswer)
> #textent = questionanswer
> self.putinfo(textent)
>
> def showinfo(self, dictent):
> #make the clues look readable
> i = 0
> listkeys = dictent.keys()
> #listkeys = listkeys.sort()
> textdisp = ''
> for item in listkeys:
> i = i+1
> istr = str(i) + " "
> question = dictent[item]
> textdisp = textdisp + istr + " the
> question is " + question + " the answer is " + item +
> "\n"
> return textdisp
>
> def newcrosswordboard(self):
> #create a crossword board
> board = []
> for square in range (NUM_SQUARES):
> board.append(EMPTY)
> return board
>
> # def newcrosswordboard(self):
> # #this is create a board with the numbers
> # board = []
> # for square in range (NUM_SQUARES):
> # text = str(square)
> # board.append(text)
> # return board
>
> def deleteclue(self):
> #delete a clue
> try:
> numberentered = self.delete_ent.get()
> dictent = self.readdict()
> numberentered = int(numberentered)
> listkeys = dictent.keys()
> i = 1
> clue = ''
> for item in listkeys:
> if numberentered == i:
> del dictent[item]
> clue = item
> break
> i = i +1
> text = "Clue " + clue + " has been removed
> the list of clues now is :-" + "\n"
> self.writedict(dictent)
> moretext = self.showinfo(dictent)
> text = text + moretext
> except:
> text = "Please enter a number as a figure"
> self.putinfo(text)
>
> def create_widgets(self):
> #create GUI
> self.question_lbl = Label(self, text = "Enter
> the question ")
> self.question_lbl.grid(row = 0, column = 0,
> columnspan = 2, sticky = W)
> self.answer_lbl = Label(self, text = "Enter
> the answer")
> self.answer_lbl.grid(row = 1, column = 0,
> columnspan = 2, sticky = W)
> self.delete_lbl = Label(self, text = "Enter
> the number of a clue you want deleted")
> self.delete_lbl.grid(row = 2, column = 0,
> columnspan = 2, sticky = W)
> #entry widget for the question
> self.question_ent = Entry(self)
> self.question_ent.grid(row=0, column = 2,
> columnspan = 1, sticky = W)
> self.answer_ent = Entry(self)
> self.answer_ent.grid(row=1, column = 2,
> columnspan = 2, sticky = W)
> self.delete_ent = Entry(self)
> self.delete_ent.grid(row=2, column = 2,
> columnspan = 1, sticky = W)
>
> #button to add entries
> Button(self, text = "Click to add clues ",
> command = self.create_questionsanswer).grid(row = 0,
> column = 3, columnspan = 3)
> Button(self, text = "Click to show clues ",
> command = self.showclues).grid(row = 1, column = 3,
> columnspan = 3)
> Button(self, text = "Click to delete clue ",
> command = self.deleteclue).grid(row = 2, column = 3,
> columnspan = 3)
> #button to create the cross word
> Button(self, text = "Click to create crossword
> ", command = self.crosswordcreation).grid(row = 16,
> column = 0, columnspan = 4)
> Button(self, text = "Click to get help ",
> command = self.helpme).grid(row = 16, column = 3,
> columnspan = 4)
> self.info_txt = Text(self, width = 80, height
> = 30, wrap = WORD)
> self.info_txt.grid(row = 20, column = 0,
> columnspan = 4)
> #show help
> self.helpme()
>
> def helpme(self):
> #get help
> helptext = 'To create crosswords add words by
> entering where it says enter the question and answer,
> then press the button "click to add clues." ' + '\n'
> helptext = helptext + 'To see all clues click
> "show all clues".'
> helptext = helptext + 'to delete a clue enter
> its number and then click delete clue. '
> helptext = helptext + 'To create a crossword
> click create crossword. The crossword will be saved
> in a file called cross.txt. '
> helptext = helptext + '\n' + 'If you like the
> crossword save the file with a different name, create
> another crossword. '
> helptext = helptext + '\n' +'Author David
> Richard Holland, this is released under the GPL
> licence'
> self.putinfo(helptext)
>
> def create_questionsanswer(self):
> #this creates the question
> questionanswer = self.readdict()
> question = self.question_ent.get()
> question = self.converttoupper(question)
> answer = self.answer_ent.get()
> answer = self.converttoupper(answer)
> textent = "This has been added to list"
> #the code below does not work properly
> if answer not in questionanswer and question
> not in questionanswer:
> questionanswer[answer] = question
> self.writedict(questionanswer)
> self.putinfo(textent)
> elif answer in questionanswer:
> self.termexists(answer)
> #########print "line 38"
> elif question in questionanswer:
> self.termexists(question)
>
>
>
> def converttoupper(self, texttoupper):
> #conver string to upper text
> try:
> texttoupper = str(texttoupper)
> texttoupper = string.upper(texttoupper)
> except:
> texttoupper = texttoupper
> return texttoupper
>
> def termexists(self, answer):
> textent = answer, 'is already an answer for
> the crossword enter another'
> self.putinfo(textent)
>
> def putinfo(self, textent):
> #put the info to the GUI
> self.info_txt.delete(0.0, END)
> self.info_txt.insert(0.0,textent)
>
> def savecross(self, textent):
> file = open('cross.txt','w')
> file.write(textent)
> file.close()
>
> def crosswordcreation(self):
> #get the board info from create crossword
> board = self.createcrossword()
> board2 = self.createcrossword()
> numhori = 0
> numvert = 0
> #########print "crossword creationcalled"
> questionanswer = self.readdict()
> #here put in code to put the answers from the
> dictionary in the board
> #code goes here
> #first sort the dictionary into 2 one with
> values > 4 in len the other one everything else
> dictshort = {}
> dictshort, dictlong =
> self.changedict(questionanswer, dictshort)
> #########print "dictionary changed"
> #variables for the questions
> diagtext = 'Across ' + '\n'
> verttext = 'Down '+ '\n'
> badquestion = 'These could not be asked' +
> '\n'
> #code to populate the board
> board, board2,numhori, numvert, diagtext,
> verttext, badquestion = self.putwordboard(dictlong,
> board, board2, numhori, numvert, diagtext, verttext,
> badquestion)
> board2, board2, numhori, numvert, diagtext,
> verttext, badquestion = self.putwordboard(dictshort,
> board, board2, numhori, numvert, diagtext, verttext,
> badquestion)
> #code to show get the board as a picture
> text = self.display_board(board)
> text = text + "\n"
> textnew = self.display_board(board2)
> text = text + textnew
> text = text + diagtext + verttext +
> badquestion #+ str(board)
> #board2 is the board that shows the clues
> #text2 = self.display_board(board3)
> #text = text + text2
> #save the cross word
> self.savecross(text)
> #display to screen
> self.putinfo(text)
> print "finished"
>
>
> def putwordboard(self, dict, board, board2,
> numhori, numvert, diagtext, verttext, badquestion):
> listkeys = dict.keys()
> #this takes the words and puts them in the
> crossword via sub functions
> item = random.choice(listkeys)
> while len(listkeys) > 0:
> # for item in listkeys:
> print item
> # emptylist, fulllist =
> self.createlist(board)
> board, board2, canbeentered, numhori,
> numvert, numbermove = self.putcharboard(item, board,
> board2, numhori, numvert)
> question = dict[item]
> question = string.capitalize(question)
> question = ' ' + question
> lenquestion = len(item)
> lenquestion = str(lenquestion)
> lenquestion = ' ' + lenquestion + "
> letters long" + '\n'
> if numbermove == 13 and canbeentered ==
> 'Yes':
> #numvert = int(numvert)
> #numvert = numvert + 1
> numvert = str(numvert)
>
> verttext = verttext + numvert +
> question + lenquestion
> numvert = int(numvert)
> textent = item + " has been entered"
> elif numbermove == 1 and canbeentered ==
> 'Yes':
> #numhori = int(numhori)
> #numhori = numhori + 1
> numhori = str(numhori)
> diagtext = diagtext + numhori +
> question + lenquestion
> numhori = int(numhori)
> textent = item + " has been entered"
> else:
> badquestion = badquestion + question
>
> #self.putinfo(textent)
> #get a new random item and remove the old
> one from the list
> item, listkeys =
> self.changenummove(listkeys, item)
> return board, board2, numhori, numvert,
> diagtext, verttext, badquestion
>
> def createlist(self, board):
> emptylist = []
> fulllist = []
> #create a list of squares which are empty and
> square which are not
> #######print NUM_SQUARES
> for square in range (NUM_SQUARES):
> if board[square] == EMPTY:
> emptylist.append(square)
> else:
> fulllist.append(square)
> return emptylist, fulllist
>
>
> def createnumbermove(self):
> #create the number in which direction to move
> listchoice = [1,13]
> numbermove = random.choice(listchoice)
> return listchoice, numbermove
>
> def changenummove(self, listchoice, numbermove):
> #change the number in which direction should
> be moved
> #make the list of options smaller
> #a = str(numbermove)
> #listchoice.remove(a)
> #the above does not work so this loop should
> do
> i = 0
> for item in listchoice:
> if item == numbermove:
> break
> else:
> i = i+1
> del listchoice[i]
> if len(listchoice) >0:
> numbermove = random.choice(listchoice)
> return numbermove, listchoice
>
> def putcharboard(self, word, board, board2,
> numhori, numvert):
> #see where the word can be put in the board
> #get a list of possible numbers that it can
> move and choose one randomly
> listchoice, numbermove =
> self.createnumbermove()
> j = 0
> i = 0
> lengthofword = len(word)
> canbeentered = 'No'
> ##########print "line 113"
> if len(USED_SQUARES) == 0:
> j = lengthofword
> #code to choose between going up or down
> #while canbeentered == 'No' and j
> > #while canbeentered == 'No' and j
> > #call a function that will see if it can be
> entered where that a letter in the word already is
> emptylist, full_list = self.createlist(board)
> #create a variable which means that it loops
> for the number of different options in numbermove
> list_choice_var = len(listchoice) +1
>
> while list_choice_var >0 and canbeentered ==
> 'No':
> ##print word, numbermove
> if len(full_list) > 0:
> try:
> canbeentered, char, j, square =
> self.canbeenteredparta( word, numbermove,
> canbeentered, lengthofword, board)
> except:
> square = 0
> #as the word can not be entered change the
> direction of move
> if canbeentered == 'No' and
> len(listchoice) > 0:
> numbermove, listchoice =
> self.changenummove(listchoice, numbermove)
> list_choice_var = list_choice_var -1
> if canbeentered == 'No':
> listchoice, numbermove =
> self.createnumbermove()
> ##print "listchoice is", listchoice,
> "numbermove is", numbermove
> j = 0
> list_choice_var = len(listchoice)
> ##print "line 308 "
> #a loop to change numbermove randomly so that
> all possible positions are entered a sub function
> sees if this can be entered
> #this code is to get find an empty square
> randomly and see if the word can be entered
> k = 0
> while list_choice_var >0 and canbeentered ==
> 'No':
> canbeentered, word, char, j, square =
> self.canbeenteredpartb(j, word, numbermove,
> canbeentered, lengthofword, board)
> k = k +1
> #print word, numbermove, "line 305",
> canbeentered
> if canbeentered == 'No' and
> len(listchoice) > 0:
> #if you can not enter it get a new
> value for the position it can be in
> ##print "line 316"
> numbermove, listchoice =
> self.changenummove(listchoice, numbermove)
> #print "line 318"
> #print "line 308", numbermove
> #reduce the variable by 1
> list_choice_var = list_choice_var -1
> #print "k is", k
> if canbeentered == 'Yes':
> #calls a function that puts the word in
> the board
> board = self.putwordinboard(word, board,
> char, square, j, numbermove, lengthofword)
>
> if numbermove == 1:
> numhori = numhori +1
> newword =
> self.createword(lengthofword, j, numhori)
> #create a new word ie a blank word
> numhori and numvert are the numbers of the questions
> board2 = self.putwordinboard(newword,
> board2, numhori, square, j, numbermove, lengthofword)
> else:
> numvert = numvert + 1
> newword =
> self.createword(lengthofword, j, numvert)
> board2 = self.putwordinboard(newword,
> board2, numvert, square, j, numbermove, lengthofword)
>
> return board, board2, canbeentered, numhori,
> numvert, numbermove
>
>
> def makecharpretty(self, char):
> #make char go in the crossword better in one
> place so that the code can be maintained better
> char = ' '+char+' '
> return char
>
> def canbeenteredparta(self, word, numbermove,
> canbeentered, lengthofword, board):
> #this sees if the word can be enterd somewhere
> it already exists
> word = str(word)
> lengthofwordnew = lengthofword
> #is a variable to show what letter in the word
> is the one to start from
> j = 0
> for char in word:
> if canbeentered == 'Yes':
> break
> emptylist, full_list =
> self.createlist(board)
> if len(full_list) > 0:
> square = random.choice(full_list)
> else:
> break
> while len(full_list) > 0:
> if canbeentered == 'Yes':
> break
> letter = self.makecharpretty(char)
> if board[square] == letter:
> #####print "square is the same
> as letter", char
> canbeentered =
> self.canbeentered(word, board, char, square, j,
> numbermove)
> #if it can be entered break the while
> loop
> if canbeentered == 'Yes':
> break
> ######print "line 364"
> elif canbeentered == 'No':
> square, full_list =
> self.changenummove(full_list, square)
> #######print "line 365"
> if canbeentered == 'Yes':
> break
> #it can be entered so break the for loop
> as well as the while otherwise increase j
> else:
> j = j +1
> return canbeentered, char, j, square
>
> def canbeenteredpartb(self, j, word, numbermove,
> canbeentered, lengthofword, board):
> #initialise variables of course these will not
> be created if the loop is not called
> char = ''
> #i = 0
> square = ''
> for char in word:
> i = 0
> #####print "char", char, "is being
> tested", "canbeentered = ", canbeentered
> copyemptylist, fullist =
> self.createlist(board)
> #######print "char is", char,"word is",
> word
> #######print "empty list is",
> copyemptylist
> if len(copyemptylist) > 0:
> square = random.choice(copyemptylist)
> #get a random square then start the loop
>
> while len(copyemptylist) > 0:
> canbeentered = self.canbeentered(word,
> board, char, square, j, numbermove)
> #########print
> canbeentered
> if canbeentered == 'Yes':
> break
> ######print "canbeentered is",
> canbeentered
> else:
> #if it can be entered we break other
> wise get a new square
> #######print "line 428", square
> square, copyemptylist =
> self.changenummove(copyemptylist, square)
> i = i +1
> ##print i
> #if this char can be entered break the for
> loop as well
> if canbeentered == 'Yes':
> break
> return canbeentered, word, char,
> j, square
> else:
> j = j +1
> #break
> return canbeentered, word, char, j, square
>
>
> def createword(self, lengthofword, numinword,
> char):
> numforward = (lengthofword - numinword) -1
> i = 0
> char = str(char)
> charnew = '-'
> while i < numforward:
> char = char + charnew

=== message truncated ===

		
---------------------------------
 ALL-NEW Yahoo! Messenger - all new features - even more fun!  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/tutor/attachments/20050112/074b4748/attachment-0001.html


More information about the Tutor mailing list