Depth first search algorithm skipping spaces in maze? - python

After concluding the first lecture of Harvard's AI course on edX, I have decided to implement the concepts taught, first being the depth-first search algorithm.
The objective of this program is to input a maze in text file mazefile and find a path from S to G using the depth-first search algorithm.
The project currently consists of 4 files, (1) the code with the class methods to operate or use the (2) text file which contains the maze, another text file (3) that contains the result file (where the AI has explored) and the main python script (4). Here they are, feel free to copy and paste these into a folder and to see how they run.
processText.py (file 1)
#code to process the mazefile file.
class importMaze:
def __init__(self,maze):
self.fileLines = []
self.fileName = maze
self.switch = False
self.toBeReturned = []
def processThis(self):
f = open(self.fileName,"r")
for x in f:
self.fileLines.append(x[:-1])
f.close()
for i in self.fileLines:
if self.switch == True:
if str(i) == "END":
self.switch = False
else:
self.toBeReturned.append(i)
else:
if str(i) == "START":
self.switch = True
return self.toBeReturned
class mazePointer:
def __init__(self,mazearray):
self.Sample = mazearray
self.initialPosition = []
for y in range(0, len(self.Sample)):
for x in range(0,len(self.Sample[y])):
if str(self.Sample[y][x]) == "S":
self.initialPosition = [x,y]
self.currentPosition = self.initialPosition
def whatIs(self,xcoordinate,ycoordinate):
return (self.Sample[ycoordinate])[xcoordinate]
def nearbyFreeSpaces(self,search):
self.freeSpaces = []
if self.whatIs(self.currentPosition[0]-1,self.currentPosition[1]) == search:
self.freeSpaces.append([self.currentPosition[0]-1,self.currentPosition[1]])
if self.whatIs(self.currentPosition[0]+1,self.currentPosition[1]) == search:
self.freeSpaces.append([self.currentPosition[0]+1,self.currentPosition[1]])
if self.whatIs(self.currentPosition[0],self.currentPosition[1]-1) == search:
self.freeSpaces.append([self.currentPosition[0],self.currentPosition[1]-1])
if self.whatIs(self.currentPosition[1],self.currentPosition[1]+1) == search:
self.freeSpaces.append([self.currentPosition[1],self.currentPosition[1]+1])
return self.freeSpaces
def moveTo(self,position):
self.currentPosition = position
TestingTrack.py (the main file)
from processText import importMaze, mazePointer
testObject = importMaze("mazefile")
environment = testObject.processThis()
finger = mazePointer(environment)
frontier = []
explored = []
result = ""
def Search():
global result
if len(finger.nearbyFreeSpaces("G")) == 1: #If the goal is bordering this space
result = finger.nearbyFreeSpaces("G")[0]
explored.append(finger.currentPosition)
else:
newPlaces = finger.nearbyFreeSpaces("F") #finds the free spaces bordering
for i in newPlaces:
if i in explored: #Skips the ones already visited
pass
else:
frontier.append(i)
while result == "":
explored.append(finger.currentPosition)
Search()
finger.moveTo(frontier[-1])
frontier.pop(-1)
exploredArray = []
for y in range(len(environment)): #Recreates the maze, fills in 'E' in where the AI has visited.
holder = ""
for x in range(len(environment[y])):
if [x,y] in explored:
holder+= "E"
else:
holder+= str(environment[y][x])
exploredArray.append(holder)
def createResult(mazeList,title,append): #Creating the file
file = open("resultfile",append)
string = title + " \n F - Free \n O - Occupied \n S - Starting point \n G - Goal \n E - Explored/Visited \n (Abdulaziz Albastaki 2020) \n \n (top left coordinate - 0,0) \n "
for i in exploredArray:
string+= "\n" + str(i)
string+= "\n \n Original problem \n"
for i in environment:
string+= "\n" +str(i)
file.write(string)
file.close()
def tracingPath():
initialExplored = explored
proceed = True
newExplored = []
for i in explored:
finger.moveTo() #incomplete
print(explored)
createResult(exploredArray,"DEPTH FIRST SEARCH", "w")
mazefile (the program will read this file to get the maze)
F - Free
O - Occupied
S - Starting point
G - Goal
(Abdulaziz Albastaki 2020)
START
OOOOOOOOOOOOOOOO
OFFFFFFFFFFFFFGO
OFOOOOOOOOOOOOFO
OFOOOOOOOOOOOOFO
OFOOOOOOOOOOOOFO
OFOOOOOOOOOOOOFO
OSFFFFFFFFFFFFFO
OOOOOOOOOOOOOOOO
END
Made by Abdulaziz Albastaki in October 2020
You can change the maze and its size however it must
-Respect the key above
-Have ONE Starting point and goal
-The maze must be in between 'START' and 'END'
-The maze MUST be surrounded by occupied space
SAMPLE PROBLEMS:
OOOOOOOOOOOOOOOO
OFFFFFFFFFFFFFGO
OFOOOOOOOOOOOOFO
OFOOOOOOOOOOOOFO
OFOOOOOOOOOOOOFO
OFOOOOOOOOOOOOFO
OSFFFFFFFFFFFFFO
OOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOO
OFOFFFFFOOOFFFOOO
OFFFOOOFOOFFOOOFO
OFOOOOOFOOFOOOOFO
OSFGFFFFFFFFFFFFO
OOOOOOOOOOOOOOOOO
There is also a resultfile, however if you would just create an empty textfile with that name (no extension), the program will fill it in with results.
The problem is with the resultfile, here it is:
DEPTH FIRST SEARCH
F - Free
O - Occupied
S - Starting point
G - Goal
E - Explored/Visited
(Abdulaziz Albastaki 2020)
(top left coordinate - 0,0)
OOOOOOOOOOOOOOOO
OFFFFFFFFFFFFFGO
OFOOOOOOOOOOOOEO
OFOOOOOOOOOOOOEO
OFOOOOOOOOOOOOEO
OEOOOOOOOOOOOOEO
OEFFFEEEEEEEEEEO
OOOOOOOOOOOOOOOO
Original problem
OOOOOOOOOOOOOOOO
OFFFFFFFFFFFFFGO
OFOOOOOOOOOOOOFO
OFOOOOOOOOOOOOFO
OFOOOOOOOOOOOOFO
OFOOOOOOOOOOOOFO
OSFFFFFFFFFFFFFO
OOOOOOOOOOOOOOOO
The AI skipped a few spaces to get to the goal, why is it doing so?
Feel free to ask me for any clarifications.

There are the following issues:
the last if block in nearbyFreeSpaces uses a wrong index:
if self.whatIs(self.currentPosition[1],self.currentPosition[1]+1) == search:
self.freeSpaces.append([self.currentPosition[1],self.currentPosition[1]+1])
should be:
if self.whatIs(self.currentPosition[0],self.currentPosition[1]+1) == search:
self.freeSpaces.append([self.currentPosition[0],self.currentPosition[1]+1])
The final position is not correctly added to the path. The last line of this block:
if len(finger.nearbyFreeSpaces("G")) == 1: #If the goal is bordering this space
result = finger.nearbyFreeSpaces("G")[0]
explored.append(finger.currentPosition)
...should be:
explored.append(result)

Related

Why it resulting a "list index out of range error" on this dijkstra algorithm

I tried to implement a dijkstra algorithm on my own graph but it doesn't run instead it says that "list index out of range"
here is the code that i tried
it works on a smaller graph like with 6 nodes but mine has 39 nodes and the maker of this code said that "At every iteration analyze the list and how the list is accessed using print()..it will help troubleshoot the error" what is that supposed to mean ?
so after a while i realized it resulting that because the algorithm reached a dead end like in node (A,B,C,AL) so when i tried to go from A to F
it reached a dead end on B, can i get a help how to fix this please ?
import sys
from heapq import heapify, heappush, heappop
def dijsktra(graph,src,dest):
inf = sys.maxsize
node_data = {'A':{'cost':inf,'pred':[]},
'B':{'cost':inf,'pred':[]},
'C':{'cost':inf,'pred':[]},
'D':{'cost':inf,'pred':[]},
'E':{'cost':inf,'pred':[]},
'F':{'cost':inf,'pred':[]},
'G':{'cost':inf,'pred':[]},
'H':{'cost':inf,'pred':[]},
'I':{'cost':inf,'pred':[]},
'J':{'cost':inf,'pred':[]},
'K':{'cost':inf,'pred':[]},
'L':{'cost':inf,'pred':[]},
'M':{'cost':inf,'pred':[]},
'N':{'cost':inf,'pred':[]},
'O':{'cost':inf,'pred':[]},
'P':{'cost':inf,'pred':[]},
'Q':{'cost':inf,'pred':[]},
'R':{'cost':inf,'pred':[]},
'S':{'cost':inf,'pred':[]},
'T':{'cost':inf,'pred':[]},
'U':{'cost':inf,'pred':[]},
'V':{'cost':inf,'pred':[]},
'W':{'cost':inf,'pred':[]},
'X':{'cost':inf,'pred':[]},
'Y':{'cost':inf,'pred':[]},
'Z':{'cost':inf,'pred':[]},
'AA':{'cost':inf,'pred':[]},
'AB':{'cost':inf,'pred':[]},
'AC':{'cost':inf,'pred':[]},
'AD':{'cost':inf,'pred':[]},
'AE':{'cost':inf,'pred':[]},
'AF':{'cost':inf,'pred':[]},
'AG':{'cost':inf,'pred':[]},
'AH':{'cost':inf,'pred':[]},
'AI':{'cost':inf,'pred':[]},
'AJ':{'cost':inf,'pred':[]},
'AK':{'cost':inf,'pred':[]},
'AL':{'cost':inf,'pred':[]},
'AM':{'cost':inf,'pred':[]},
}
node_data[src]['cost'] = 0
visited = []
temp = src
for i in range(38):
if temp not in visited: # TODO: Reassign source
visited.append(temp)
min_heap = []
for j in graph[temp]:
if j not in visited:
cost = node_data[temp]['cost'] + graph[temp][j]
if cost < node_data[j]['cost']:
node_data[j]['cost'] = cost
node_data[j]['pred'] = node_data[temp]['pred'] + [temp]
heappush(min_heap,(node_data[j]['cost'],j))
heapify(min_heap)
temp = min_heap[0][1]
print("Shortest Distance: " + str(node_data[dest]['cost']))
print("Shortest Path: " + str(node_data[dest]['pred'] + list(dest)))
if __name__ == "__main__":
graph = {
'A':{'D':105.3},
'B':{'E':65},
'C':{'AM':103.4},
'D':{'A':105.3,'E':132.8,'J':165.8},
'E':{'B':65,'D':132.8,'F':176.6,'H':78.3},
'F':{'E':176.6,'R':181.8,'AM':20.3},
'G':{'H':63,'K':57.2},
'H':{'E':78.3,'G':63,'I':65,'O':101.2},
'I':{'H':65,'P':104},
'J':{'D':165.8,'K':125.6,'L':25.9},
'K':{'G':57.2,'J':125.6,'N':37.5},
'L':{'J':25.9,'M':68,'Y':177.7},
'M':{'L':25.9,'N':56,'V':124},
'N':{'K':37.5,'M':56,'O':77.4},
'O':{'H':101.2,'N':77.4,'P':70.2,'W':128.6},
'P':{'I':104,'O':70.2,'Q':68},
'Q':{'P':68,'R':45,'T':102.9},
'R':{'F':181.8,'Q':45,'S':51},
'S':{'R':51,'U':104.3,'AM':193.3},
'T':{'Q':102.9,'U':84.35,'X':21.6},
'U':{'S':104.3,'A':84.35,'AF':160.7},
'V':{'M':124,'W':128,'Z':45},
'W':{'O':128.6,'V':128,'X':150.7,'AD':132.9},
'X':{'T':21.6,'W':150.7,'AE':166.8},
'Y':{'L':177.7,'Z':100.9,'AA':39.8},
'Z':{'V':45,'Y':100.9,'AB':34},
'AA':{'Y':39.8,'AB':100.3,'AH':258.5},
'AB':{'Z':34,'AA':100.3,'AC':47.8},
'AC':{'AB':47.8,'AD':126,'AH':60.37},
'AD':{'W':132.9,'AE':110.2,'AK':93.14,'AC':126},
'AE':{'X':166.8,'AI':82.2,'AD':110.2},
'AF':{'U':160.7,'AG':13.7,'AI':181.2},
'AG':{'AF':13.7},
'AH':{'AA':285.5,'AC':60.37,'AJ':33.8},
'AI':{'AE':82.2,'AF':181.2,'AK':110},
'AJ':{'AH':33.8,'AK':119.3,'AL':52},
'AK':{'AD':93.14,'AI':110,'AJ':119.3},
'AI':{'AJ':52},
'AM':{'C':103.4,'S':193.3,'F':20.3}
}
source = 'A'
destination = 'F'
dijsktra(graph,source,destination)
it said error instead on this line
temp = min_heap[0][1]

Cyclic relations between nodes A>B>C>A

This is how it looks like before and after, for the problem am trying to solve using Python. I have been trying for weeks. And am failing so miserable to tell Python to do the following:
STEP1: If you find on this document: "LinkedTo=" * (Example value: Node_3)*
STEP2: Then Stop
STEP3: Go to the previous NodePosX= and copy the value * (Example value: 10)*
STEP4: Go to the previous NotePosY= and copy the value * (Example value: 100)*
STEP5: Then find the next "Node_3" on the document
STEP6: And replace inside the NodePosX=30 and NodePosY=300 for the copied values 10 and 100
STEP7: Then look for the next "LinkedTo=" * (Example value: Node_5)* and repeat the STEP2 to STEP5
This is how it looks like Before running the Python script:
Begin
Name="Node_1"
NodePosX=10
NodePosY=100
LinkedTo=Node_3
LinkedTo=Node_5
End Object
Begin
Name="Node_2"
NodePosX=20
NodePosY=200
End Object
Begin
Name="Node_3"
NodePosX=30
NodePosY=300
End Object
Begin
Name="Node_4"
NodePosX=40
NodePosY=400
End Object
Begin
Name="Node_5"
NodePosX=50
NodePosY=500
End Object
This is how it should look like AFTER running the Python script:
Begin
Name="Node_1"
NodePosX=10
NodePosY=100
LinkedTo=Node_3
LinkedTo=Node_5
End Object
Begin
Name="Node_2"
NodePosX=20
NodePosY=200
End Object
Begin
Name="Node_3"
NodePosX=10
NodePosY=100
End Object
Begin
Name="Node_4"
NodePosX=40
NodePosY=400
End Object
Begin
Name="Node_5"
NodePosX=10
NodePosY=100
End Object
Do you think am asking to much from Python to do?
Any better suggestions for the title to this problem?
I hired a developer and this is the code they wrote
'''
By: Alex Reichenbach
'''
import re
begin_regex = re.compile("Begin")
name_regex = "(?<=Name=\"Node_).*(?=\")"
posX_regex = "(?<=NodePosX=).*"
posY_regex = "(?<=NodePosY=).*"
linkedTo_regex = "(?<=LinkedTo=).*"
end_regex = re.compile("End Object")
## Reading the contents of the file
text = open("1-Example-Original.txt", "r").read()
class Node:
def __init__(self):
self.name = ""
self.nodePosX = 0
self.nodePosY = 0
self.linked_to = []
def __str__(self):
linked = ""
for l in self.linked_to:
linked += "\nLinkedTo="+l
return """Begin
Name="%s"
NodePosX=%s
NodePosY=%s%s
End Object
"""%(self.name, self.nodePosX, self.nodePosY, linked)
## Read the text into the node objects
nodes = []
current_node = None
for line in text.split('\n'): ## Iterate through each line
if begin_regex.match(line): ## Begin
current_node = Node()
nodes.append(current_node)
elif re.findall(name_regex, line): ## Name
name = re.findall(name_regex, line)[0]
current_node.name = name
elif re.findall(posX_regex, line): ## PosX
posX = re.findall(posX_regex, line)[0]
current_node.nodePosX = posX
elif re.findall(posY_regex, line): ## PosY
posY = re.findall(posY_regex, line)[0]
current_node.nodePosY = posY
elif re.findall(linkedTo_regex, line): ## LinkedTo
name = re.findall(linkedTo_regex, line)[0]
current_node.linked_to.append(name)
## Copy the linked_to attributes
for i in range(len(nodes)):
for j in range(i, len(nodes)):
node1 = nodes[i]
node2 = nodes[j]
if node2.name in node1.linked_to:
node2.nodePosX = node1.nodePosX
node2.nodePosY = node1.nodePosY
## Print it all out
s = ""
for node in nodes:
s += str(node)
print(s)
## Write to File?
open("_edited.txt", "w").write(s)

Python unified diff with line numbers from both "files"

I'm trying to figure out a way to create unified diffs with line numbers only showing N lines of context. I have been unable to do this with difflib.unified_diff. I need to show changes in both files.
The closest I can come is using diff on the command line like so:
/usr/bin/diff
--unchanged-line-format=' %.2dn %L'
--old-line-format="-%.2dn %L"
--new-line-format="+%.2dn %L"
file1.py
file2.py
BUT I only want to show N lines of context, and /usr/bin/diff doesn't seem to support context with a custom line format (eg. -U2 is not compatible with --line-format "conflicting output style options").
Below is an example of what I'd like to accomplish (the same output as the above diff, but only showing 1 line of context surrounding changes):
+01: def renamed_function()
-01: def original_function():
02:
+03: """ Neat stuff here """
04:
21:
+22: # Here's a new comment
23:
85: # Output the value of foo()
+86: print "Foo is %s"%(foo())
-86: print foo()
87:
I was able to figure out something very close to what I wanted to do. It's slower than regular diff, though. Here's the entire code, from my project GitGate.
def unified_diff(to_file_path, from_file_path, context=1):
""" Returns a list of differences between two files based
on some context. This is probably over-complicated. """
pat_diff = re.compile(r'## (.[0-9]+\,[0-9]+) (.[0-9]+,[0-9]+) ##')
from_lines = []
if os.path.exists(from_file_path):
from_fh = open(from_file_path,'r')
from_lines = from_fh.readlines()
from_fh.close()
to_lines = []
if os.path.exists(to_file_path):
to_fh = open(to_file_path,'r')
to_lines = to_fh.readlines()
to_fh.close()
diff_lines = []
lines = difflib.unified_diff(to_lines, from_lines, n=context)
for line in lines:
if line.startswith('--') or line.startswith('++'):
continue
m = pat_diff.match(line)
if m:
left = m.group(1)
right = m.group(2)
lstart = left.split(',')[0][1:]
rstart = right.split(',')[0][1:]
diff_lines.append("## %s %s ##\n"%(left, right))
to_lnum = int(lstart)
from_lnum = int(rstart)
continue
code = line[0]
lnum = from_lnum
if code == '-':
lnum = to_lnum
diff_lines.append("%s%.4d: %s"%(code, lnum, line[1:]))
if code == '-':
to_lnum += 1
elif code == '+':
from_lnum += 1
else:
to_lnum += 1
from_lnum += 1
return diff_lines

Two issue about python OpenOPC library

Issues description and environments
The OpenOPC library is friendly and easy to use, the api is simple too, but I have found two issues during the development of a tool to record real time OPC items data.
The development environment is: Window 8.1, Python 2.7.6, wxpython 2.8 unicode
The testing environment is: Window XP SP3, Python 2.7.6, wxpython 2.8 unicode, Rockwell's soft logix as OPC Server
The deploy environment is: Window XP SP3, connected with Rockwell's real PLC, installed RSLogix 5000 and RSLinx Classic Gateway
Questions
the opc.list function doesn't list all the item of specify node both in testing and workstaion environment. The question is how to list the 't' from the opc server?
An int array 'dint100' and a dint 't' is added with RS logix 5000 at the scope of soft_1
With the default OPC client test tool from Rockwell it could list the new added 't'
With OpenOPC library, I couldn't find out how to list the item 't', but I could read it's value by opc.read('[soft_1]t') with it's tag.
If the 't' could be listed, it could be added into the IO tree of my tool.
The opc.servers function will encounter an OPCError on the deploy environment, but the client could connect the 'RSLinx OPC Server' directly with the server name. Does opc.servers function dependent on some special dll or service?
Any suggestions will be appreciated! Thanks in advance!
Consider that the browsing problems ("opc.list") may not be on your side. RSLinx is notorious for its broken OPC browsing. Try some test/simulation server from a different vendor, to test this hypothesis.
I realize that I'm really late to this game. I found what was causing this issue. OpenOPC.py assumes that there cannot be both a "Leaf" and a "Branch" on the same level. Replace the function ilist with this:
def ilist(self, paths='*', recursive=False, flat=False, include_type=False):
"""Iterable version of list()"""
try:
self._update_tx_time()
pythoncom.CoInitialize()
try:
browser = self._opc.CreateBrowser()
# For OPC servers that don't support browsing
except:
return
paths, single, valid = type_check(paths)
if not valid:
raise TypeError("list(): 'paths' parameter must be a string or a list of strings")
if len(paths) == 0: paths = ['*']
nodes = {}
for path in paths:
if flat:
browser.MoveToRoot()
browser.Filter = ''
browser.ShowLeafs(True)
pattern = re.compile('^%s$' % wild2regex(path) , re.IGNORECASE)
matches = filter(pattern.search, browser)
if include_type: matches = [(x, node_type) for x in matches]
for node in matches: yield node
continue
queue = []
queue.append(path)
while len(queue) > 0:
tag = queue.pop(0)
browser.MoveToRoot()
browser.Filter = ''
pattern = None
path_str = '/'
path_list = tag.replace('.','/').split('/')
path_list = [p for p in path_list if len(p) > 0]
found_filter = False
path_postfix = '/'
for i, p in enumerate(path_list):
if found_filter:
path_postfix += p + '/'
elif p.find('*') >= 0:
pattern = re.compile('^%s$' % wild2regex(p) , re.IGNORECASE)
found_filter = True
elif len(p) != 0:
pattern = re.compile('^.*$')
browser.ShowBranches()
# Branch node, so move down
if len(browser) > 0:
try:
browser.MoveDown(p)
path_str += p + '/'
except:
if i < len(path_list)-1: return
pattern = re.compile('^%s$' % wild2regex(p) , re.IGNORECASE)
# Leaf node, so append all remaining path parts together
# to form a single search expression
else:
###################################### JG Edit - Flip the next two rows comment/uncommented
p = '.'.join(path_list[i:])
# p = string.join(path_list[i:], '.')
pattern = re.compile('^%s$' % wild2regex(p) , re.IGNORECASE)
break
###################################### JG Edit - Comment this to return to original
browser.ShowBranches()
node_types = ['Branch','Leaf']
if len(browser) == 0:
lowest_level = True
node_types.pop(0)
else:
lowest_level = False
for node_type in node_types:
if node_type=='Leaf':
browser.ShowLeafs(False)
matches = filter(pattern.search, browser)
if not lowest_level and recursive:
queue += [path_str + x + path_postfix for x in matches]
else:
###################################### JG Edit - Flip the next two rows comment/uncommented
if lowest_level or node_type=='Leaf': matches = [exceptional(browser.GetItemID,x)(x) for x in matches]
# if lowest_level: matches = [exceptional(browser.GetItemID,x)(x) for x in matches]
if include_type: matches = [(x, node_type) for x in matches]
for node in matches:
if not node in nodes: yield node
nodes[node] = True
###################################### Uncomment this to return to original
# browser.ShowBranches()
# if len(browser) == 0:
# browser.ShowLeafs(False)
# lowest_level = True
# node_type = 'Leaf'
# else:
# lowest_level = False
# node_type = 'Branch'
# matches = filter(pattern.search, browser)
# if not lowest_level and recursive:
# queue += [path_str + x + path_postfix for x in matches]
# else:
# if lowest_level: matches = [exceptional(browser.GetItemID,x)(x) for x in matches]
# if include_type: matches = [(x, node_type) for x in matches]
# for node in matches:
# if not node in nodes: yield node
# nodes[node] = True
except pythoncom.com_error as err:
error_msg = 'list: %s' % self._get_error_str(err)
raise OPCError(error_msg)

for loop to insert things into a tkinter window

I have Tkinter program that has to add a significant amount of data to the window so I tried to write a for loop to take care of it but since I have to use a string variable for the name of the object that Tkinter is running .insert() on the object. I didn't explain it very well here is the method
def fillWindow(self):
global fileDirectory
location = os.path.join(fileDirectory, family + '.txt')
file = open(location, 'r')
ordersDict = {}
for line in file:
(key, value) = line.split(':', 1)
ordersDict[key] = value
for key in ordersDict:
ordersDict[key] = ordersDict[key][:-2]
for item in ordersDict:
if item[0] == '#':
if item[1] == 'o':
name = 'ordered%s' %item[2:]
right here is the problem line because I have the variable that matches the name of the entry object already created but 'name' is actually a string variable so it gives me the error "AttributeError: 'str' object has no attribute 'insert'"
name.insert(0,ordersDict[item])
here is the entire class. It makes a Tkinter window and fills it with a sort of shipping screen so all the entries are for how many orders of a certain thing are needed. I'm also very new so I know that I do things the long way a lot.
class EditShippingWindow(Tkinter.Toplevel):
def __init__(self, student):
Tkinter.Toplevel.__init__(self)
self.title('Orders')
family = student
## Window Filling
ageGroupLabel = Tkinter.Label(self,text='Age Group')
ageGroupLabel.grid(row=0,column=0)
itemColumnLabel = Tkinter.Label(self,text='Item')
itemColumnLabel.grid(row=0, column=1)
costColumnLabel = Tkinter.Label(self,text='Cost')
costColumnLabel.grid(row=0, column=2)
orderedColumnLabel = Tkinter.Label(self,text='Ordered')
orderedColumnLabel.grid(row=0, column=3)
paidColumnLabel = Tkinter.Label(self,text='Paid')
paidColumnLabel.grid(row=0, column=4)
receivedColumnLabel = Tkinter.Label(self,text='Received')
receivedColumnLabel.grid(row=0, column=5)
#Item Filling
column1list = ['T-Shirt (2T):$9.00', 'T-Shirt (3T):$9.00', 'T-Shirt (4T):$9.00',
'Praise Music CD:$10.00', ':', 'Vest L(Size 6):$10.00', 'Vest XL(Size 8):$10.00',
'Hand Book (KJ/NIV):$8.75', 'Handbook Bag:$6.00', 'Memory CD (KJ/NIV):$10.00',
':', 'Vest L(size 10):$10.00', 'Vest XL(Size 12):$10.00', 'Hand Glider (KJ/NIV/NKJ):$10.00',
'Wing Runner (KJ/NIV/NKJ):$10.00', 'Sky Stormer (KJ/NIV/NKJ):$10.00', 'Handbook Bag:$5.00',
'Memory CD (S/H/C):$10.00', 'Hand Glider Freq. Flyer:$8.00', 'Wing Runner Freq. Flyer:$8.00',
'Sky Stormer Handbook:$8.00' , ':', 'Uniform T-Shirt Size (10/12/14):$13.00',
'Uniform T-Shirt Size(10/12/14):$13.00', 'Uniform T-Shirt(Adult S / M / L / XL):$13.00',
'3rd & 4th Gr. Book 1 (KJ / NIV / NKJ):$8.75', '3rd & 4th Gr. Book 2 (KJ / NIV / NKJ):$8.75',
'4th & 5th Gr. Book 1 (KJ / NIV / NKJ):$8.75', '4th & 5th Gr. Book 2 (KJ / NIV / NKJ):$8.75',
'Memory CD 3rd & 4th Gr. Book (1/2):$10.00', 'Drawstring Backpack:$5.50']
column1num = 1
for item in column1list:
num = str(column1num)
(title, price) = item.split(':')
objectName1 = 'column1row' + num
objectName1 = Tkinter.Label(self,text=title)
objectName1.grid(row=column1num, column=1)
objectName2 = 'column1row' + num
objectName2 = Tkinter.Label(self,text=price)
objectName2.grid(row=column1num, column=2)
column1num += 1
#Ordered Paid Recieved Filler
for i in range(32):
if i == 11 or i == 22 or i == 0 or i == 5:
pass
else:
width = 10
# First Column
title1 = 'ordered' + str(i)
self.title1 = Tkinter.Entry(self,width=width)
self.title1.grid(row=i,column=3)
#self.title1.insert(0, title1)
#Second
title2 = 'paid' + str(i)
self.title2 = Tkinter.Entry(self,width=width)
self.title2.grid(row=i,column=4)
#self.title2.insert(0, title2)
#Third
title3 = 'received' + str(i)
self.title3 = Tkinter.Entry(self,width=width)
self.title3.grid(row=i,column=5)
#self.title3.insert(0, title3)
## Methods
def fillWindow(self):
global fileDirectory
location = os.path.join(fileDirectory, family + '.txt')
file = open(location, 'r')
ordersDict = {}
for line in file:
(key, value) = line.split(':', 1)
ordersDict[key] = value
for key in ordersDict:
ordersDict[key] = ordersDict[key][:-2]
for item in ordersDict:
if item[0] == '#':
if item[1] == 'o':
self.name = 'ordered%s' %item[2:]
self.name.insert(0,ordersDict[item])
fillWindow(self)
It looks like you have a conceptual error there: inside this method, the variable "name" does not exist up to the last line on the first listing. Then it is created, and points to an ordinary Python string -- if you are using a "name" variable elsewhere on your class that variable does not exist inside this method.
For an easy fix of your existing code, try calling the variable as "self.name" instead of just name where it is created, and on your last line in this method use:
self.name.insert(0,ordersDict[item]) instead.
The self. prefix will turn your variable into an instance variable, which is shared across methods on the same instance of the class.
On a side note, you don' t need even the dictionary much less three consecutive for loops on this method, just insert the relevant values you extract from "line" in your text variable.

Categories

Resources