Первое, что я заметил, это то, что вы определяете A
как пустой словарь, а затем перезаписываете этот пустой словарь с помощью self.animal
, который является списком.
A={}
A=self.animal
Итак, я 'Я не уверен, что ты собираешься делать здесь.Затем в вашем определении B
вы нарезаете его:
B = [(A[0], "%.2f" % (reduce(mul,A[3:])*A[2][i]/sigma*A[2][i])) for A in A]
Это не совпадает с либо определением A
, потому что вы не можете нарезать голос, ноначальный индекс, который вы выбрали, - 3
, а самый высокий индекс в self.animal
- 2
.Смешение!Но при более внимательном рассмотрении становится ясно, что проблема в том, что вы повторно используете A
в качестве индексной переменной.Вы действительно не должны этого делать;это делает этот код невероятно запутанным.
Это также может привести к ошибкам.Рассмотрим этот код:
>>> a = range(10)
>>> [a for a in a]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a
9
Как видите, понимание списка заставляет a
ссылаться на последнее значение в последовательности, ранее известной как a
.Это не происходит в вашем коде, потому что вы использовали выражение генератора.Но это все еще трудно читать и сбивать с толку.Я настоятельно рекомендую сделать это вместо:
sigma = float(sum(reduce(mul,item[3:]) for item in A))
B = [(item[0], "%.2f" % (reduce(mul,item[3:])/sigma)) for item in A]
Обновление : ОК, после внесения этих изменений вам все еще нужно get
данные из весов.В вашем определении self.animal
вы используете self.soil.get()
, например, так:
('Odocoileous virginiana','White-tailed Deer',self.soil.get(),0.99,0.01,0.99)
Это возвращает возвращаемое значение self.soil.get()
в кортеж.Но тогда это значение фиксируется - оно никогда не изменится.Вы должны явно вызывать self.soil.get()
каждый раз, когда вы хотите обновить значение.Кроме того, ваше понимание списка никогда не получит доступ к возвращенному значению.Вы нарезаете их так:
>>> l = ('Odocoileous virginiana','White-tailed Deer',
... self.soil.get(), 0.99, 0.01, 0.99)
>>> l[3:]
(0.98999999999999999, 0.01, 0.98999999999999999)
Помните, что индексирование в списках и кортежах начинается с 0
- так в приведенном выше кортеже l
, l[0] == 'Odocoileous virginiana'
.Поэтому, если вы хотите всего, кроме первых двух вещей, вы должны вырезать из индекса 2:
>>> l[2:]
(0.55000000000000004, 0.98999999999999999, 0.01, 0.98999999999999999)
Но это по-прежнему не решает проблему с корнем, то есть вы должны вызвать self.soil.get()
дляполучить обновленные данные.Один из способов сделать это - просто воссоздать self.animal
при каждом нажатии кнопки отправки.Это было бы расточительно, но это сработало бы.Менее расточительный (но все же неловкий) подход заключается в сохранении самой функции в кортеже, а не в результате функции.Вы бы сделали это так:
>>> l = ('Odocoileous virginiana','White-tailed Deer',
... self.soil.get, 0.99, 0.01, 0.99)
Обратите внимание на отсутствие ()
после self.soil.get
.Теперь кортеж содержит не значение с плавающей запятой, а функцию, которая возвращает значение с плавающей запятой.Вы должны вызвать его, чтобы получить значение, но оно возвращает полностью обновленное значение каждый раз.Чтобы объединить функции, вы можете использовать lambda
:
>>> l = ('Odocoileous virginiana','White-tailed Deer',
... lambda: self.soil.get() * self.water.get(), 0.99, 0.01, 0.99)
Теперь вы можете вызвать l[2]
, чтобы получить значение:
>>> l[2]()
0.30250000000000005
Итак, чтобы сложить все вместе, у вас естьчтобы немного разбить понимание списка, явно вызвать l[2]
, но как только вы это сделаете, это должно сработать.Это не идеальная настройка, но, боюсь, мне придется оставить создание улучшенной архитектуры в качестве упражнения для читателя.