python 错误:AttributeError: 'NoneType' 对象没有属性 'getIndex'

问题描述 投票:0回答:0

我朋友写了一个BFS代码。它对她有用,但是当我在 python IDLE 中尝试时,它显示了这条消息: 这是完整的代码: 节点.py:

from enum import IntEnum

# You can get the enumeration based on integer value, or make comparison
# ex: d = Direction(1), then d would be Direction.NORTH
# ex: print(Direction.SOUTH == 1) should return False
class Direction(IntEnum):
    NORTH = 1
    SOUTH = 3
    WEST  = 2
    EAST  = 4

class Successor:
    def __init__(self,successor ,direction, length=1):
        self.SNode=successor
        self.direction=Direction(direction)
        self.length=length
        


# Construct class Node and its member functions
# You may add more member functions to meet your needs
class Node:
    def __init__(self, index=0):
        self.index = index
        self.snumber=0
        # store successor as (Node, index ,direction to node, distance)
        self.Successors = []
        self.OSuccessors = []
        self.pathList=[]
        self.nodecount=-1

    def getIndex(self):
        return self.index

    def getSuccessors(self):
        s=self.Successors
        print("Successor list of ",self.getIndex(),": ")
        for u in s:
            if(u.SNode.nodecount>=0):
                print(u.SNode.getIndex(),"is used")
                s.remove(u)
            else:
                print("Node",u.SNode.getIndex(),":", "length:", u.length, "direction: ", u.direction,u.SNode.nodecount)
        return s

    def setSuccessor(self, successor, direction, length=1):
        o= Successor(successor,direction)
        self.OSuccessors.append(o)
        a=self
        i=1
        while(i<length):
            b=Node(self.getIndex()*10000+successor.getIndex()*100+i)
            a.addSuccessor(b,direction)
            a=b
            i+=1
        s= Successor(successor,direction,length)
        a.Successors.append(s)
        #print("For Node",a.getIndex(),", #",a.snumber," successor",s.SNode.getIndex(),"is set.")
        return
    
    def addSuccessor(self, successor,direction):
        s= Successor(successor,direction)
        self.Successors.append(s)
        #print("For Node",self.getIndex(),", #",self.snumber," successor",s.SNode.getIndex(),"is set.")
        return    

    def getDirection(self, nd):
        for succ in self.OSuccessors:
            if succ.SNode.getIndex() == nd.getIndex():
                #print(nd.getIndex(),"is in the", succ.direction,"direction of ",self.getIndex())
                return succ.direction
        print("the given node is not adjacent")
        return 0

    def isSuccessor(self, nd):
        for succ in self.OSuccessors:
            if succ.SNode.getIndex()== nd.getIndex():
                #print(nd.getIndex(),"is adjacent with", self.getIndex())
                return True
        #print(nd.getIndex(),"is not adjacent with", self.getIndex())
        return False
    


TN=Node(1)
TN1=Node(0)
TN2=Node(2)
TN3=Node(3)
print("----------------------------")
TN.setSuccessor(TN2,Direction.EAST,5)
TN.setSuccessor(TN3,Direction.SOUTH,3)
TN.getSuccessors()
print("----------------------------")
TN.isSuccessor(TN1)
TN.getDirection(TN1)
#TN.getLength(TN1)
print("----------------------------")
TN.isSuccessor(TN2)
TN.getDirection(TN2)
#TN.getLength(TN2)
print("----------------------------")
TN.isSuccessor(TN3)
TN.getDirection(TN3)
print(TN.OSuccessors[1].direction)
#TN.getLength(TN3)
print("----------------------------")

迷宫.py:

from node import *
import numpy as np
import csv
import pandas
from enum import IntEnum
import math

class Action(IntEnum):
    ADVANCE = 1
    U_TURN = 2
    TURN_RIGHT = 3
    TURN_LEFT = 4
    HALT = 5
    
class Maze:
    
    def searchNode(self, ind):
        for n in self.nodes:
            if(n.getIndex()==ind):
                return n
        print("there is no such node as: ",ind)
        return None
    
    def __init__(self, filepath):
        # TODO : read file and implement a data structure you like
        # For example, when parsing raw_data, you may create several Node objects.  
        # Then you can store these objects into self.nodes.  
        # Finally, add to nd_dict by {key(index): value(corresponding node)}
        self.raw_data = pandas.read_csv(filepath).values
        #print("-------------------------------------------")
        #print("Raw data =\n",self.raw_data)
        #print("-------------------------------------------")
        self.nodeNumber = self.raw_data.__len__()
        #print("-------------------------------------------")
        #print("Node number =",self.nodeNumber) 
        #print("-------------------------------------------")
        self.nodes = []
        #print("-------------------------------------------")
        #print("Nodes =",)
        for N in self.raw_data:
            n=Node(N[0])
            self.nodes.append(n)
       # print("-------------------------------------------")
        for N in self.raw_data:
            if(N[1]!=0):
                a=self.searchNode(N[1])
                self.nodes[N[0]-1].setSuccessor(a, Direction.NORTH, N[5])
            if(N[2]!=0):
                a=self.searchNode(N[2])
                self.nodes[N[0]-1].setSuccessor(a, Direction.SOUTH, N[6])
            if(N[3]!=0):
                a=self.searchNode(N[3])
                self.nodes[N[0]-1].setSuccessor(a, Direction.WEST, N[7])
            if(N[4]!=0):
                a=self.searchNode(N[4])
                self.nodes[N[0]-1].setSuccessor(a, Direction.EAST, N[8])   
        self.nd_dict =[]  # key: index, value: the correspond node       
            
    def getStartPoint(self):
        if (len(self.nd_dict) < 2):
            print("Error: the start point is not included.")
            return 0
        return self.nd_dict[1]

    def getNodeDict(self):
        return self.nd_dict

    def BFS(self, nd):
        print("----------------BFS----------------")
        # TODO : design your data structure here for your algorithm
        nd.nodecount=0
        nd.pathList.append((0,nd,0))
        Q=[]
        Q.append(nd.getSuccessors())
        for u in nd.getSuccessors():
            u.SNode.nodecount=nd.nodecount+1 
            u.SNode.pathList.append(nd)
            u.SNode.pathList.append(u.SNode)
           # print("========================================")
            print(nd.getIndex(),"to",u.SNode.getIndex(),"(",u.SNode.nodecount,")")   
            #print("========================================")
        
        for x in Q:
            for u in x:
                Q.append(u.SNode.getSuccessors())
               # print("origin: ",u.SNode.getIndex())
                for v in u.SNode.getSuccessors():
                    #print("next node",v.SNode.getIndex())
                    if(v.SNode.nodecount<0):
                        v.SNode.nodecount=u.SNode.nodecount+1
                        for a in u.SNode.pathList:
                            v.SNode.pathList.append(a)                        
                        v.SNode.pathList.append(v.SNode)
                      #  print("========================================")
                        print(u.SNode.getIndex(),"to",v.SNode.getIndex(),"(",u.SNode.nodecount,")")
                       # print("========================================")  
        # Tips : return a sequence of nodes from the node to the nearest unexplored deadend
        return None

    def BFS_2(self, nd_from, nd_to):
        # TODO : similar to BFS but with fixed start point and end point
        self.BFS(nd_from)
        for a in nd_to.pathList:
            if(a.getIndex()<100):
                self.nd_dict.append(a.getIndex())
        print("----------------result from",nd_from.getIndex(),"to",nd_to.getIndex(),"-----------------")
        # Tips : return a sequence of nodes of the shortest path
        return None

    def getAction(self, car_dir, nd_from, nd_to):
        # TODO : get the car action
        # Tips : return an action and the next direction of the car if the nd_to is the Successor of nd_to
        new_dir = nd_from.getDirection(nd_to)
        print(((new_dir+4-car_dir)%4))
        if(nd_from==nd_to):
            A = Action.HALT 
        else:
            if(new_dir==0):
                return 0
            if(((new_dir+4-car_dir)%4)==1):
                A = Action.TURN_RIGHT
            if(((new_dir+4-car_dir)%4)==3):
                A = Action.TURN_LEFT
            if(((new_dir+4-car_dir)%4)==2):
                A = Action.U_TURN
            if(((new_dir+4-car_dir)%4)==0):
                A = Action.ADVANCE
        # If not, print error message and return 0
        print(A)
        return A

    def getActions(self, nodes):
        # TODO : given a sequence of nodes, return the corresponding action sequence
        # Tips : iterate through the nodes and use getAction() in each iteration
        return None

    def actions_to_str(self, actions):
        # cmds should be a string sequence like "fbrl....", use it as the input of BFS checklist #1
        cmd = "fbrls"
        cmds = ""
        for action in actions: cmds += cmd[action-1]
        print(cmds)
        return cmds

    def strategy(self, nd):
        return self.BFS(nd)

    def strategy_2(self, nd_from, nd_to):
        return self.BFS_2(nd_from, nd_to)

M=Maze('small_maze.csv')
#M.BFS_2(M.searchNode(3),M.searchNode(1))
M.getAction(Direction.EAST,M.searchNode(3),M.searchNode(2))
#M.getNodeDict()
#M.actions_to_str(Action(Action.TURN_LEFT))

这是我们的 csv 文件: "nan" 可能是 csv 文件中的空白空间

我怎样才能让它发挥作用?

node.py最后的代码可以,但是当我在maze.py中使用getIndex()或nodecount方法时,就不行了。我也尝试将 maze.py 的末尾更改为:

M=Maze('small_maze.csv')
M.searchNode(3.0)

但还是这样显示: 我认为它应该只有一行“如果没有这样的节点:nan” 我是 python 的新手,希望有人能帮助我。

python attributeerror
© www.soinside.com 2019 - 2024. All rights reserved.