Найти - Пользователи
Полная версия: Проблемы с Google Spreadsheet
Начало » Python для экспертов » Проблемы с Google Spreadsheet
1
aCL
Сломал себе всю голову.
Решил написать сначала в ветке “Python для Новичков”, но почему-то передумал

Вступление:
Есть Google Таблица (далее просто таблица), столбцы Номер , Баланс, и ещё ряд ячеек

Есть скрипт. В нем реализован класс параметров номера, в т.ч. атрибуты row (номер строки, в которой находится номер в таблице) и cells (список ячеек таблицы, находящиеся на той же строке, что и номер)

Есть словарь base, в котором ключ - это номер телефона, а значение - экземпляр класса параметров номера.

Использую модуль gspread.

wks_range - список всех ячеек таблицы. Один элемент списка - это экземпляр класса gspread.cell с атрибутами row,cell и value. Если вывести на экран один из элементов списка, выглядеть будет так:
<Cell R63C1 '9629429549'>

Очевидно, R - номер строки, в которой находится ячейка, C - номер столбца, строка - значение ячейки

Часть скрипта:

for num in base.keys():
    for cell in wks_range:
        if base[num].row==cell.row:
            base[num].cells.append(cell)#ячейки, относящиеся к номеру
Предполагается, что максимальная длина списка base.cells не может быть больше 4. По факту список cells экземпляров класса (предполагаю, что на всех номерах - во время тестов проверял один случайно выбранный ключ ) содержит все ячейки таблицы.

Если в интерактивном режиме, после отработки скрипта, проверки и обнаружения ошибки запустить следующее:
>>> for num in base.keys():
	base[num].cells=[]
	
>>> for num in base.keys():
	for cell in wks_range:
		if base[num].row==cell.row and base[num].row!=None:
			base[num].cells.append(cell)
	if len(base[num].cells)>4:
		print(num)

То результатов никаких не выводится, т.е. в интерактивном режиме максимальная длина списка такая, какая и должна быть.
Подскажите, пожалуйста, в чем тут фишка?
aCL
два варианта:
for num in list(base.keys())[:30]:
    for cell in wks_range:
        if base[num].row==cell.row:
            base[num].cells.append(cell)
вывожу результат:
>>> base['9030064337'].cells
[<Cell R220C1 '9037551123'>, <Cell R220C2 '-1782.88'>, <Cell R220C3 None>, <Cell R220C4 None>, <Cell R51C1 '9030064337'>, <Cell R51C2 '-5003.47'>, <Cell R51C3 None>, <Cell R51C4 None>, <Cell R130C1 '9055669265'>, <Cell R130C2 '-1710.2'>, <Cell R130C3 None>, <Cell R130C4 None>, <Cell R128C1 '9096659444'>, <Cell R128C2 '-1910.98'>, <Cell R128C3 None>, <Cell R128C4 None>, <Cell R135C1 '9039648669'>, <Cell R135C2 '-1643.36'>, <Cell R135C3 None>, <Cell R135C4 None>, <Cell R122C1 '9637824205'>, <Cell R122C2 '-2403.7'>, <Cell R122C3 None>, <Cell R122C4 None>, <Cell R126C1 '9091655819'>, <Cell R126C2 '-1959.54'>, <Cell R126C3 None>, <Cell R126C4 None>, <Cell R101C1 '9032170808'>, <Cell R101C2 '-3079.33'>, <Cell R101C3 None>, <Cell R101C4 None>, <Cell R226C1 '9099923523'>, <Cell R226C2 '-1671.60'>, <Cell R226C3 None>, <Cell R226C4 None>, <Cell R179C1 '9032122624'>, <Cell R179C2 '-2739.83'>, <Cell R179C3 None>, <Cell R179C4 None>, <Cell R29C1 '9057361883'>, <Cell R29C2 '-7253.05'>, <Cell R29C3 None>, <Cell R29C4 None>, <Cell R71C1 '9652548777'>, <Cell R71C2 '-3012.87'>, <Cell R71C3 None>, <Cell R71C4 None>, <Cell R6C1 '9031301949'>, <Cell R6C2 '-7185.78'>, <Cell R6C3 None>, <Cell R6C4 None>]



и практически тот же самый код, только не append, а print:
...
if base[num].row==cell.row:
            print('{} {} {}'.format(num,base[num].row,cell))
9030064337 51 <Cell R51C1 '9030064337'>
9030064337 51 <Cell R51C2 '-5003.47'>
9030064337 51 <Cell R51C3 None>
9030064337 51 <Cell R51C4 None>

какая-то проблема в append'е? или где?
py.user.next
эти кусочки кода мало что говорят

aCL
какая-то проблема в append'е? или где?
да, ты его не чистишь
где? вот прямо в том месте, которое не выложил
aCL
Чистить? Зачем чистить? Нужно каждому экземпляру класса передать те ячейки, row которых совпадает с row номера. If их должен отбирать. И почему-то этого не делает - вернее делает, но только в интерактивном режиме.

Строки, которые я в первом посте назвал “часть скрипта”, как и строки кода во втором посте - последние. Дальше все закомментировал, пока не разберусь с проблемой.

И какая, в сущности, разница? Мне очевидно, что проблема в выложенном коде. Представлены даже варианты, когда не работающий if работает, но не так, как нужно - либо последующей обработкой в интерактивном режиме, либо print'ом. Что, естественно, не устраивает.

Кстати, пробовал убирать лишние ячейки методом класса (код при необходимости выложу позднее - сижу с телефона )
Убирает. Но как-то произвольно. У экземпляров длина списка cells получается произвольной - от 1 до 10. Хотя должна быть чётко фиксированной, исходя из начальных условий - 4.
py.user.next
aCL
Чистить? Зачем чистить?
чтобы append() начинался с пустого списка

aCL
код при необходимости выложу позднее - сижу с телефона
нужно знать, где создаётся base и где запускается данный цикл

aCL
for num in base.keys():
не думаю, что у тебя настолько старый питон, что нет итерации по ключам словаря
for num in base:
aCL
py.user.next
чтобы append() начинался с пустого списка
при создании экземпляра класса атрибуту cells присваивается пустой список, а уже потом в каждый из экземпляров добавляются необходимые значения cells

py.user.next
не думаю, что у тебя настолько старый питон, что нет итерации по ключам словаря
3.3. Я просто только учусь


Код во вложении.
Методы класса удалил, т.к. не используются до проблемного места. Все, что после - тоже убрал.

Использую оптимизированный под свои нужды модуль mysql.connector, называется db1

Проблемное место - в конце.

И, как Вы понимаете, запускать его не имеет смысла
py.user.next
aCL
class slot_param():
    def __init__(self,
                 phone=None,#номер телефона, для проверки
                 balans=None,#баланс номера
                 groups=None,#строка, затем список групп
                 trafs=None,#текущий траффик
                 dl=None,#дилер
                 activation=None,#дата активации
                 status=None,#
                 bill=None,#последний счет
                 row=None,#номер строки, в которой находится номер и его параметры в файлике
                 delay=None,#отсрочка
                 num_2_send=None,#номер для отправки сообщений
                 text=None,#текст для отправки сообщений
                 bill_prev=None,#предыдущий счет. узнается, если есть действующая delay_m
                 call_status=None,#статус звонка. 0 - не звонить, 1 - звонить
                 call_rezults=None,#результаты предыдущего обзвона
                 call_instr=None,#инструкции обзвона
                 cell_instr=None,#ячейки номера
                 cells=[],
                 prev_rez=None):#предыдущие результаты
        self.phone=str(phone)
        self.balans=balans        
        self.trafs=trafs
        self.dl=dl
        self.bill=bill
        self.bill_prev=bill_prev
        self.activation=activation
        self.delay=delay
        self.status=status
        self.groups=groups
        self.row=row
        self.num_2_send=num_2_send
        self.text=text
        self.call_status=call_status
        self.prev_rez=prev_rez
        self.cells=cells
    #метод для обработки параметров номера
    def up_params(self):
        pass

аналог
>>> class A:
...     def __init__(self, lst=[]):
...         self.lst = lst
...     def m(self):
...         self.lst.append(1)
...         print(self.lst)
... 
>>> a1 = A()
>>> a1.m()
[1]
>>> a2 = A()
>>> a2.m()
[1, 1]
>>>

как надо
>>> class A:
...     def __init__(self, lst=[]):
...         self.lst = lst[:]
...     def m(self):
...         self.lst.append(1)
...         print(self.lst)
... 
>>> a1 = A()
>>> a1.m()
[1]
>>> a2 = A()
>>> a2.m()
[1]
>>>
aCL
Т.е. при создании экземпляра класса первого номера передается пустой список, затем ему в цикле добавляются cells, у которых row совпадает с row номера. При создании экземпляра второго номера передаётся уже не пустой список, а список с cells первого экземпляра и т.д.?

А почему так происходит? И в чем разница простой передачи списка с передачей ? Или где про это прочитать?)
py.user.next
все экземпляры привязаны к одному и тому же списку - первому, потому что он находится в формальных параметрах метода

python.org. binding

>>> def f(a=1, b=[], c=()):
...     print(id(a), id(b), id(c))
... 
>>> f()
1287271584 3073828716 3075457068
>>> f()
1287271584 3073828716 3075457068
>>> f()
1287271584 3073828716 3075457068
>>>
aCL
Туговато с английским, простите)
На досуге попробую осилить
И спасибо
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB