From: Dave McCormick on
John,
Interesting and confusing...
I tested my code on Ubuntu 8.04, Win XP and 7, and WinMob before I
called it "good". And of course your modifications work on all too.

"""
* rename get_position() to get_complete_text()
* replace new_Rword(), new_Bword(), and new_Gword() with a single
function that has an extra parameter, "color".
"""
The first easy, the second is going to take some thinking....
Keep at it I will. I am hooked!!! Being able to write once and run on
all of the above platforms is amazing!!!

Thanks again!!!
Dave

John Posner wrote:
> On Sat, Jan 2, 2010 at 1:47 PM, Dave McCormick wrote:
>
>> WooHoo!!!
>> I got it!!! Yup, I am sure it can be optimized but it works!!!
>
> Dave, please ignore a couple of my bogus complaints in the previous
> message:
>
> ... you call function new_Rword() before you define it
>
> ... this version also has the advantage of defining each function
> just once, instead of multiple times on each keystroke
>
>
> But I stand by my overall statement that the program didn't work for
> me, and that rearranging the lines produces a working program.
>
> -John
From: John Posner on
On Fri, 01 Jan 2010 21:01:04 -0500, Cousin Stanley
<cousinstanley(a)gmail.com> wrote:

<snip>
>
> I was not familiar with the re.finditer method
> for searching strings ...

Stanley and Dave --

So far, we've just been using finditer() to perform standard-string
searches (e.g. on the word "red"). Since Dave now wants to color multiple
words the same color (e.g. the words in redList), we can use a single
regular-expression search to locate *all* the words in a list. This
eliminates the need to use a "for" loop to handle the list. Here's what I
mean:

>>> import re
>>> s = "it is neither red nor crimson, but scarlet, you see"

########## individual searches

>>> [matchobj.span() for matchobj in re.finditer("red", s)]
[(14, 17)]
>>> [matchobj.span() for matchobj in re.finditer("crimson", s)]
[(22, 29)]
>>> [matchobj.span() for matchobj in re.finditer("scarlet", s)]
[(35, 42)]

########## one "swell foop"

>>> redList = "red crimson scarlet".split()
>>> redList_regexp = "|".join(redList)
>>> redList_regexp
'red|crimson|scarlet'
>>> [matchobj.span() for matchobj in re.finditer(redList_regexp, s)]
[(14, 17), (22, 29), (35, 42)]

-John
From: Dave McCormick on


John Posner wrote:
> On Fri, 01 Jan 2010 21:01:04 -0500, Cousin Stanley
> <cousinstanley(a)gmail.com> wrote:
>
> <snip>
>>
>> I was not familiar with the re.finditer method
>> for searching strings ...
>
> Stanley and Dave --
>
> So far, we've just been using finditer() to perform standard-string
> searches (e.g. on the word "red"). Since Dave now wants to color
> multiple words the same color (e.g. the words in redList), we can use
> a single regular-expression search to locate *all* the words in a
> list. This eliminates the need to use a "for" loop to handle the list.
> Here's what I mean:
>
> >>> import re
> >>> s = "it is neither red nor crimson, but scarlet, you see"
>
> ########## individual searches
>
> >>> [matchobj.span() for matchobj in re.finditer("red", s)]
> [(14, 17)]
> >>> [matchobj.span() for matchobj in re.finditer("crimson", s)]
> [(22, 29)]
> >>> [matchobj.span() for matchobj in re.finditer("scarlet", s)]
> [(35, 42)]
>
> ########## one "swell foop"
>
> >>> redList = "red crimson scarlet".split()
> >>> redList_regexp = "|".join(redList)
> >>> redList_regexp
> 'red|crimson|scarlet'
> >>> [matchobj.span() for matchobj in re.finditer(redList_regexp, s)]
> [(14, 17), (22, 29), (35, 42)]
>
> -John
Thanks again John,
This is fun!!!
I made a "red.text" file to hold the "red words", they are separated by
a space in the file.
Still need to add the extra parameter "color" someplace. But this is
what I have so far.
##############
file = 'red.txt'
file = open("red.txt","r")
rList = file.readlines()
file.close()
redList = str(rList).split()
blueList = "blue ball".split()
greenList = "green grass".split()
def get_complete_text(event):
complete_text = Tbox.get("1.0", END)
Tbox.tag_remove("red", "1.0", END)
Tbox.tag_remove("blue", "1.0", END)
Tbox.tag_remove("green", "1.0", END)
####RED########
redList_regexp = "|".join(redList)
for matchobj in re.finditer(redList_regexp, complete_text):
start,end = matchobj.span()
Tbox.tag_add("red", "1.0 + %d chars" % start,"1.0 + %d chars" % end)
Tbox.tag_config("red", foreground="red")
####BLUE#######
blueList_regexp = "|".join(blueList)
for matchobj in re.finditer(blueList_regexp, complete_text):
start,end = matchobj.span()
Tbox.tag_add("blue", "1.0 + %d chars" % start,"1.0 + %d chars" %
end)
Tbox.tag_config("blue", foreground="blue")
####GREEN#######
greenList_regexp = "|".join(greenList)
for matchobj in re.finditer(greenList_regexp, complete_text):
start,end = matchobj.span()
Tbox.tag_add("green", "1.0 + %d chars" % start,"1.0 + %d chars"
% end)
Tbox.tag_config("green", foreground="green")
From: John Posner on
On Tue, 05 Jan 2010 10:31:09 -0500, Dave McCormick <mackrackit(a)gmail.com>
wrote:

> ... But this is what I have so far.
> ##############
> file = 'red.txt'
> file = open("red.txt","r")
> rList = file.readlines()
> file.close()
> redList = str(rList).split()

Dave, you're doing exactly the right thing: gradually expanding your
program, to provide more functionality and to learn more about the
available programming tools. It's also very good that you take care to
close() the file after processing it. Now for the bad news ...

1. Don't use "file" as a variable name -- it's a built-in object type.
(Some people don't like the fact that Python allows you to redefine such
"reserved words".)

2. It's probably not the best idea to use a single variable (you use
"file") to do double-duty: to hold the name of a file, and to hold the
open-file object returned by the open() function. It's perfectly legal,
but it hides information that might be useful when you're debugging a
program. This is better:

fname = 'red.txt'
inpf = open(fname, "r")

3. It might be better to use read() rather than readlines() to process the
"red.txt" file. It depends on what that file is supposed to contain. For
example, if you expect "red.txt" to contain exactly one line, which has
one or more words, you can process the open-file object like this:

file_contents = inpf.read()
redList = file_contents.split()

... or ...

redList = inpf.read().split()

It's certainly a mistake to use the expression "str(rList).split()". Using
str() to convert the list "rList" into a string creates a mess that
includes square-bracket characters. Did this actually work for you?

Best,
John

From: Dave McCormick on


John Posner wrote:
>
> Dave, you're doing exactly the right thing: gradually expanding your
> program, to provide more functionality and to learn more about the
> available programming tools. It's also very good that you take care to
> close() the file after processing it. Now for the bad news ...
Seems like there is always bad news :)
>
> 1. Don't use "file" as a variable name -- it's a built-in object type.
> (Some people don't like the fact that Python allows you to redefine
> such "reserved words".)
>
> 2. It's probably not the best idea to use a single variable (you use
> "file") to do double-duty: to hold the name of a file, and to hold the
> open-file object returned by the open() function. It's perfectly
> legal, but it hides information that might be useful when you're
> debugging a program. This is better:
>
> 3. It might be better to use read() rather than readlines() to process
> the "red.txt" file. It depends on what that file is supposed to
> contain. For example, if you expect "red.txt" to contain exactly one
> line, which has one or more words, you can process the open-file
> object like this:
All noted and fixed.
>
> It's certainly a mistake to use the expression "str(rList).split()".
> Using str() to convert the list "rList" into a string creates a mess
> that includes square-bracket characters. Did this actually work for you?
It sort of worked. With one color file it seemed fine but after I
posted I added another color file and things fell apart.
Now with the above fixes it works with three colors from three files.
When the list are printed to the shell the list look like this:
redList ['red', 'dog', 'apple', '#']
blueList ['blue', 'ball', 'berry']
greenList ['green', 'grass', 'do']

But another problem is noticed. It does not matter if the list is built
in code or from a file.
If dog is entered, "do" will be green with the "g" being red.
Back to the drawing board.....

Here is the complete code"
######
from Tkinter import *
import re
RFfile = 'red.txt'
inpRF = open(RFfile,"r")
rList = inpRF.read()
inpRF.close()

BFfile = 'blue.txt'
inpBF = open(BFfile,"r")
bList = inpBF.read()
inpBF.close()

GFfile = 'green.txt'
inpGF = open(GFfile,"r")
gList = inpGF.read()
inpGF.close()

def get_complete_text(event):
complete_text = Tbox.get("1.0", END)
redList = str(rList).split()
blueList = str(bList).split()
greenList = str(gList).split()
print "redList",redList
print "blueList",blueList
print "greenList",greenList
Tbox.tag_remove("red", "1.0", END)
Tbox.tag_remove("blue", "1.0", END)
Tbox.tag_remove("green", "1.0", END)
####RED########
redList_regexp = "|".join(redList)
for matchobj in re.finditer(redList_regexp, complete_text):
start,end = matchobj.span()
Tbox.tag_add("red", "1.0 + %d chars" % start,"1.0 + %d chars" % end)
Tbox.tag_config("red", foreground="red")
####BLUE#######
blueList_regexp = "|".join(blueList)
for matchobj in re.finditer(blueList_regexp, complete_text):
start,end = matchobj.span()
Tbox.tag_add("blue", "1.0 + %d chars" % start,"1.0 + %d chars" %
end)
Tbox.tag_config("blue", foreground="blue")
####GREEN#######
greenList_regexp = "|".join(greenList)
for matchobj in re.finditer(greenList_regexp, complete_text):
start,end = matchobj.span()
Tbox.tag_add("green", "1.0 + %d chars" % start,"1.0 + %d chars"
% end)
Tbox.tag_config("green", foreground="green")

root = Tk()
Tbox = Text(root, width=40, height=15, wrap=CHAR,
font="Times 14 bold", bg="#dddddd")
Tbox.pack()
Tbox.bind("<KeyRelease>", get_complete_text)
Tbox.focus()
root.mainloop()
####
Thanks again,
Dave