Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> кривой append или у меня что-то с головой..помогие 
:(
    Опции темы
newsTester
  Дата 23.5.2009, 01:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 29.3.2008

Репутация: нет
Всего: нет



хочу описать класс взвешенного графа в котором есть список ребер и список вершин. Хочу ввести его из файла содержащего список смежности вот таким методом

Код

    def add_edge(cls, init_string = "0\t0\t0"):

        if init_string.count('\n'):
            pos = init_string.index('\n')
            init_string = init_string[:pos]

        pos = init_string.index('\t')
        vertex_1 = init_string[:pos]
        init_string = init_string[pos + 1:]
        
        pos = init_string.index('\t')
        length = float(init_string[pos + 1:])
        vertex_2 = init_string[:pos]

        if not cls.vertexes.count(vertex_1):
            cls.vertexes.append(vertex_1)

        if not cls.vertexes.count(vertex_2):
            cls.vertexes.append(vertex_2)

        edge = Edge(vertex_1, vertex_2, length)

        if not cls.edges.count(edge):
            cls.edges.append(edge)
            


так вот. Список vertexes заполняется нормально, а в списке edges оказывается куча ребер равных последнему (причем похоже что ВСЕ ребра УСТАНАВЛИВАЮТСЯ равными последнему ребру из списка) smile . И это при том что функция вызывается отдельно для ввода каждого ребра...

точнее вершины всех ребер равны вершинам последнего ребра, а длины все разные и идут в обратном порядке... В общем все признаки сумасшедствия на лицо

Это сообщение отредактировал(а) newsTester - 23.5.2009, 01:27
PM MAIL   Вверх
Daevaorn
Дата 23.5.2009, 06:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 9
Всего: 70



Цитата(newsTester @  23.5.2009,  02:18 Найти цитируемый пост)
хочу описать класс взвешенного графа в котором есть список ребер и список вершин. Хочу ввести его из файла содержащего список смежности вот таким методом

Сократите ваш код до минимального, продуцирующего на ваш взгляд не правильное поведение. Разбираться в вашей предметной области и додумывать те части, которые вы не привели желания нет.
PM MAIL WWW   Вверх
alex_smirnov
Дата 23.5.2009, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 194
Регистрация: 22.6.2007
Где: Санкт-Петербург

Репутация: 2
Всего: 4



Проблема в том, что мы не знаем, что из себя представляет объект cls (имеет-ли он поля edges и vertexes? ; ).
Также, было бы неплохо увидеть стектрэйс ошибок.
PM GTalk Jabber   Вверх
newsTester
Дата 24.5.2009, 00:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 53
Регистрация: 29.3.2008

Репутация: нет
Всего: нет



И так есть два замечание первое что кода слишком много, второе что информации слишком мало... Попытаюсь исправиться.

Цитата

Сократите ваш код до минимального, продуцирующего на ваш взгляд не правильное поведение. 

Проблема в том что по моему не правильно работает вот этот кусок
Код

        if not cls.edges.count(edge):
            cls.edges.append(edge)

А аналогичный ему (опять таки по моему) вот этот кусок
Код

        if not cls.vertexes.count(vertex_1):
            cls.vertexes.append(vertex_1)

        if not cls.vertexes.count(vertex_2):
            cls.vertexes.append(vertex_2)


работает корректно..
И понять в чем разница я никак не могу.

Цитата

Проблема в том, что мы не знаем, что из себя представляет объект cls (имеет-ли он поля edges и vertexes? ; ).

В принципе никаких секретов и примудростей в cls вроде нет. Весь модуль выглядит примерно так (cls имеет тип Graph), но использует объекты типа Edge.
Код

class Edge:

    vertexes = [0, 0]
    length = 0

    def __init__(cls, vertex_1 = 0, vertex_2 = 0, length = 0):
        cls.vertexes[0] = vertex_1
        cls.vertexes[1] = vertex_2
        cls.length = length

    def __getitem__(cls, key):
        return cls.vertexes[key]

class Graph:
    vertexes = []
    edges = []

    def add_edge(cls, init_string = "0\t0\t0"):

        if init_string.count('\n'):
            pos = init_string.index('\n')
            init_string = init_string[:pos]

        pos = init_string.index('\t')
        vertex_1 = init_string[:pos]
        init_string = init_string[pos + 1:]
        
        pos = init_string.index('\t')
        length = float(init_string[pos + 1:])
        vertex_2 = init_string[:pos]

        if not cls.vertexes.count(vertex_1):
            cls.vertexes.append(vertex_1)

        if not cls.vertexes.count(vertex_2):
            cls.vertexes.append(vertex_2)

        edge = Edge(vertex_1, vertex_2, length)

        if not cls.edges.count(edge):
            cls.edges.append(edge)
            
    def __init__(cls, file_name):
        import os
        file_list = open(file_name, 'r').readlines()

        for line in file_list:
            cls.add_edge(line)

Може я действительно где-то рядом ошибаюсь..

Цитата

Также, было бы неплохо увидеть стектрэйс ошибок. 

а вот этого я вам уже не покажу, т.к. его просто нет. Тут просто edges заполняется не корректными данными, т.е. ошибка получается логическая. Суть ошибки примерно в следующем при вводе 
Код

11    21    31
12    22    32
13    23    33

хочется увидеть
Код

([[11, 21], 31]
 [[12, 22], 32]
 [[13, 23], 33])

а получается
Код

([[13, 23], 33]
 [[13, 23], 32]
 [[13, 23], 31])


ну вроде так толжнобыть понятней... Но лично я всеравно так ничего и не могу понять
PM MAIL   Вверх
Hydrevt
Дата 24.5.2009, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 9.10.2008

Репутация: нет
Всего: нет



Очень похоже, что проблема аналогична моей (ответ - http://forum.vingrad.ru/index.php?showtopi...t&p=1868989, ещё раз спасибо Daevaorn): vertexes и length у Вас - атрибуты класса, а не объекта. Соответственно, они делятся между всеми экземплярами Edge. Решение - не обозначать их в классе, а только присваивать в конструкторе:
Код

class Edge:
    def __init__(cls, vertex_1 = 0, vertex_2 = 0, length = 0):
        cls.vertexes = [vertex_1, vertex_2]
        cls.length = length
    def __getitem__(cls, key):
        return cls.vertexes[key]

(Работоспособность проверил)
P. S. С атрибутами Graph у Вас полностью аналогичная ситуация - так что всё хорошо будет только если на всю программу будет один-единственный граф.
Ещё есть предложение сократить код и повысить удобочитаемость, заменив
Код

        if init_string.count('\n'):
            pos = init_string.index('\n')
            init_string = init_string[:pos]
        pos = init_string.index('\t')
        vertex_1 = init_string[:pos]
        init_string = init_string[pos + 1:]
        
        pos = init_string.index('\t')
        length = float(init_string[pos + 1:])
        vertex_2 = init_string[:pos]

на 
Код

        init_string = init_string.split('\n')[0]
        (vertex_1, vertex_2, length) = init_string.split('\t', 2)

(Работоспособность также проверена на Вашем примере.)
P. P. S. Описание ещё в чём-то аналогичных вашим "граблей": http://www.intuit.ru/department/pl/python/3/2.html - "Примечание" и текст под ним, а также http://www.intuit.ru/department/pl/python/2/4.html - про модуль copy

Это сообщение отредактировал(а) Hydrevt - 24.5.2009, 09:49
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Python: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1221 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.