The above image was fourth image generated by Stable Diffusion when inputted “Python Dictionary Parser”.
As a quick recap: last post, I covered my process in which I defined a python dictionary including every five-letter word in the downloaded dictionary, created inlaid for-loops to select two words in a way that every word would be compared to every other word (where w selected the first word and v selected the second word), created inlaid for-loops to select two letters in a way that every letter in the first word (w) was compared to the second word (v), and added one “point” to each word for every indirect intersection they had.
As a reminder, for uniformity, I’ll use the term “Direct Intersection” to refer to letters that are congruent and are located in congruent positions within a word; comparing the words “apple” and “angle” results in three direct intersections: “a__le”. In addition, I’ll use the term “Indirect Intersection” to refer to letters that appear in both words, but are not in the same position; comparing the words “intel” and “tenet”, we have indirect intersections for “n”, 2″t”, 2″e”. Notice that despite an e being a direct intersection, it is also an indirect intersection. All direct intersections are also indirect intersections, but not necessarily vice-versa.
In amelioration of my code, I decided to make a few quality of life improvements to my variable naming; it’s also important to see what corresponds to what in order to keep things consistent.
Code by the end of last post:
f = open("words_alpha.txt")
bigChunkofText = f.read()
words = bigChunkofText.split('\n')
words_5 = []
for w in words:
if len(word)==5:
words_5.append(word)
dict = {}
for w in words_5:
dict[w] = 0
for v in words_5:
for o in range (0,4):
for m in range (0,4):
if w[o] == v[m]:
dict[w] += 1
for w in sorted(dict, key=dict.get, reverse=False):
print(w, dict[w])
Ameliorated Code:
f = open("words_alpha.txt")
bigChunkofText = f.read()
words = bigChunkofText.split('\n')
words_5 = []
for word in words:
if len(word)==5:
words_5.append(word)
dict = {}
for word in words_5:
dict[word] = 0
for vord in words_5:
for letter1check in range (0,len(word)-1):
for letter2check in range (0,len(vord)-1):
if (word[letter1check] == vord[letter1check]):
dict[word] += 1
for word in sorted(dict, key=dict.get, reverse=False):
print(word, dict[word])
Essentially, the variables that were renamed are the following:w → wordv → vordo → letter1checkm → letter2check
In addition, to make the code more modular (especially if we wanted to compare words of more or less than 5 letters), I replaced digit 4 with len(word)-1 and len(vord)-1 so that the letters in the word that are tested adapt by word length.
Now, to tackle the issue of scoring:
– For the sake of simplicity, we can allow indirect intersections to count as 1 point. This can serve as a baseline to assign point values to other things.
– Because direct intersections verify the correct placement of the letter as well as the correct letter, it is the equivalent of testing five indirect intersections and returning the correct one; it therefore makes sense to add 5 points for every direct intersection. We can test for this using:
if (word[letter1check] == vord[letter1check]):
– Duplicate indirect intersections are redundant; there’s no use to count the indirect intersections for “p” twice between apple and panel, because the letter “p”, if panel is typed in, can only appear once regardless.
So the first thing that needed to be implemented in my code was the testing for direct intersections. Mathematically speaking, a direct intersection is when a letter in digit-place n from word 1 is equivalent to the letter in digit-place n from word 2. To translate this into code, if our two words are word and vord, and the digit-place for the word is letter1check, we can write an if statement to check for direct intersections, which as mentioned above, would be the following:for letter1check in range (0,len(word)-1):
if (word[letter1check] == vord[letter1check]):
Notice that letter2check isn’t used at all to test direct intersections. This is simply due to the fact that because in direct intersections, the places in both words must be the same; instead of having 5×5 ways of testing intersections, we only have 5: digit-places: 0, 1, 2, 3, and 4. Therefore, simply using letter1check sufficed to test direct intersections. To assign 5 points to each direct intersection, we can add the line dict[word] += 5 under this conditional statement.
Now, we also need to address duplicate intersections. This includes instances where a direct and indirect intersection in a word exist simultaneously; if there is a direct intersection, similar to reasons stated above, it becomes redundant to count the indirect intersection, so we don’t count it. One strategy to accomplish this is through binary classification. Basically, in binary classification, elements are separated into two categories (hence the use of binary and classification in the name). In many cases, binary classification is used to denote whether or not an event has happened, with 0 indicating that it didn’t, and 1 indicating that it did. In application to this project, we can treat each letter as a separate event, and with binary classification, label whether or not a letter has already been used in an intersection.
To implement binary classification, we will need to add another for loop around everything we already have, to test every single letter for every single word. However, before implementing this, we need to create an array that we can reference for every letter, which looks like this:
a=b=c=d=e=f=g=h=i=j=k=l=m=n=o=p=q=r=s=t=u=v=w=x=y=z=() Letterchecks = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]
This looks a lot like spaghetti code, but actually is a really simple way to insert every letter in an array. We also need to initialize a dictionary to assign the values of each of these letters (0 or 1), so we can make one with dictletter = {}. After a complete implementation of the binary classification, we have this short chunk of code:
for Letter in Letterchecks:
dictletter[Letter] = 0
for word in words_5:
dict[word] = 0
for vord in words_5:
for letter1check in range (0,len(word)-1):
if dictletter[Letter] == 0:
if (word[letter1check] == vord[letter1check]) == str(Letter):
dict[word] += 5
dictletter[Letter] = 1
for letter2check in range (0,len(vord)-1):
if dictletter[Letter] == 0:
if word[letter1check] == str(Letter) == vord[letter2check]:
dict[word] += 1
dictletter[Letter] = 1
dictletter[Letter] = 0
for word in sorted(dict, key=dict.get, reverse=False):
print(word, dict[word])
This essentially checks:
- Has the letter been intersected before?
if dictletter[Letter] == 0:- If not, is there a direct intersection with that letter?
if (word[letter1check] == vord[letter1check]) == str(Letter):- If so, add 5 points to the word and mark the letter as used
dict[word] += 5dictletter[Letter] = 1
- If so, add 5 points to the word and mark the letter as used
- If not, is there an indirect intersection with that letter?
if word[letter1check] == str(Letter) == vord[letter2check]:- If so, If so, add 1 point to the word and mark the letter as used
dict[word] +=1dictletter[Letter] = 1
- If so, If so, add 1 point to the word and mark the letter as used
- If not, is there a direct intersection with that letter?
