AttributeError:' float'对象没有属性' get_coords'

时间:2017-09-02 20:55:29

标签: python-3.x attributeerror

我从这个讲座中学习Python:Lec 19 | MIT 6.00 Introduction to Computer Science and Programming。我使用Python 3.6.2,讲座示例在Python 2.x上运行。什么是在函数ans_quest中设置x和y值的正确方法?

x, y = loc_list[-1].get_coords()

这种方法可以这样调用吗?这就是讲座中的例子。

完整代码:

import math, random, pylab, copy

class Location(object):
    def __init__(self, x, y):
        self.x = float(x)
        self.y = float(y)
    def move(self, xc, yc):
        return Location(self.x+float(xc), self.y+float(yc))
    def get_coords(self):
        return self.x, self.y
    def get_dist(self, other):
        ox, oy = other.get_coords()
        x_dist = self.x - ox
        y_dist = self.y - oy
        return math.sqrt(x_dist**2 + y_dist**2)

class Compass_Pt(object):
    possibles = ('N', 'S', 'E', 'W')
    def __init__(self, pt):
        if pt in self.possibles: self.pt = pt
        else: raise ValueError('in Compass_Pt.__init__')

    def move(self, dist):
        if self.pt == 'N': return (0, dist)
        elif self.pt == 'S': return (0, -dist)
        elif self.pt == 'E': return (dist, 0)
        elif self.pt == 'W': return (-dist, 0)
        else: raise ValueError('in Compass_Pt.move')

class Field(object):
    ''' Cartesian plane where object will be located '''
    def __init__(self, drunk, loc):
        self.drunk = drunk
        self.loc = loc
    def move(self, cp, dist):
        old_loc = self.loc
        xc, yc = cp.move(dist)
        self.loc = old_loc.move(xc, yc)
    def get_loc(self):
        return self.loc
    def get_drunk(self):
        return self.drunk

class Drunk(object):
    ''' Point itself '''
    def __init__(self, name):
        self.name = name
    def move(self, field, cp, dist = 1):
        if field.get_drunk().name != self.name:
            raise ValueError('Drunk.move called with drunk not in the field')
        for i in range(dist):
            field.move(cp, 1)

class Usual_Drunk(Drunk):
    def move(self, field, dist = 1):
        ''' Drunk.move superclass method override. Sends additional cp attribute.'''
        cp = random.choice(Compass_Pt.possibles)
        Drunk.move(self, field, Compass_Pt(cp), dist)


class Cold_Drunk(Drunk):
    def move(self, field, dist = 1):
        cp = random.choice(Compass_Pt.possibles)
        if cp == 'S':
            Drunk.move(self, field, Compass_Pt(cp), 2*dist)
        else:
            Drunk.move(self, field, Compass_Pt(cp), dist)

class EW_Drunk(Drunk):
    def move(self, field, time = 1):
        cp = random.choice(Compass_Pt.possibles)
        while cp != 'E' and  cp != 'W':
            cp = random.choice(Compass_Pt.possibles)
        Drunk.move(self, field, Compass_Pt(cp), time)

def perform_trial(time, f):
    start = f.get_loc()
    distances = [0,0]
    for t in range(1, time + 1):
        f.get_drunk().move(f)
        new_loc = f.get_loc()
        distance = new_loc.get_dist(start)
        distances.append(distance)
    return distances

def perform_sim(time, num_trials, drunk_type):
    dist_lists = []
    loc_lists = []
    for trial in range(num_trials):
        d = drunk_type('Drunk' + str(trial))
        f = Field(d, Location(0, 0))
        distances = perform_trial(time, f)
        locs = copy.deepcopy(distances)
        dist_lists.append(distances)
        loc_lists.append(locs)
    return dist_lists, loc_lists


def ans_quest(max_time, num_trials, drunk_type, title):
    dist_lists, loc_lists = perform_sim(max_time, num_trials, drunk_type)
    means = []
    for t in range(max_time + 1):
        tot = 0.0
        for dist_l in dist_lists:
            tot += dist_l[t]
        means.append(tot/len(dist_lists))
    pylab.figure()
    pylab.plot(means)
    pylab.ylabel('distance')
    pylab.xlabel('time')
    pylab.title('{} Ave. Distance'.format(title))
    lastX = []
    lastY = []
    for loc_list in loc_lists:
        x, y = loc_list[-1].get_coords()
        lastX.append(x)
        lastY.append(y)
    pylab.figure()
    pylab.scatter(lastX, lastY)
    pylab.ylabel('NW Distance')
    pylab.title('{} Final location'.format(title))
    pylab.figure()
    pylab.hist(lastX)
    pylab.xlabel('EW Value')
    pylab.ylabel('Number of Trials')
    pylab.title('{} Distribution of Final EW Values'.format(title))


num_steps = 50
num_trials = 10


ans_quest(num_steps, num_trials, Usual_Drunk, 'Usual Drunk ' + str(num_trials) + ' Trials')
ans_quest(num_steps, num_trials, Cold_Drunk, 'Cold Drunk ' + str(num_trials) + ' Trials')
ans_quest(num_steps, num_trials, EW_Drunk, 'EW Drunk ' + str(num_trials) + ' Trials')

pylab.show()

错误:

Traceback (most recent call last):
  File "/home/tihe/Documents/CODING/Project Home/Python/biased_random_walks.py", line 194, in <module>
    ans_quest(num_steps, num_trials, Usual_Drunk, 'Usual Drunk ' + str(num_trials) + ' Trials')
  File "/home/tihe/Documents/CODING/Project Home/Python/biased_random_walks.py", line 175, in ans_quest
    x, y = loc_list[-1].get_coords()
AttributeError: 'float' object has no attribute 'get_coords'

1 个答案:

答案 0 :(得分:0)

如果您有Location个对象的列表,则可以像这样调用此方法。该错误是因为loc_list填充了距离而不是Location个对象。这种情况发生在函数perform_sim中,而不是根据您正在制作distance的深层副本的位置。

也许你可以尝试这样的事情:

def perform_trial(time, f):
    start = f.get_loc()
    distances = [0,0]
    locations = []
    for t in range(1, time + 1):
        f.get_drunk().move(f)
        new_loc = f.get_loc()
        locations.append(new_loc)
        distance = new_loc.get_dist(start)
        distances.append(distance)
    return distances, locations

def perform_sim(time, num_trials, drunk_type):
    dist_lists = []
    loc_lists = []
    for trial in range(num_trials):
        d = drunk_type('Drunk' + str(trial))
        f = Field(d, Location(0, 0))
        distances, locations = perform_trial(time, f)
        dist_lists.append(distances)
        loc_lists.append(locations)
    return dist_lists, loc_lists

我希望能帮到你。