Использование Zip для обработки виджетов, помеченных как включенные - PullRequest
0 голосов
/ 27 мая 2018

Этот код возвращает список виджетов из диапазона электронной таблицы, у которого есть другой диапазон, указывающий, что он включен для обработки.Код работает, но он плохо реализован, особенно с точки зрения правильного использования zip и макета.

Я вполне уверен, что zip и ws.iter_cols должны быть частью ответа, но не налучший способ их использования.Единственная значимая строка - это понимание списка под комментарием Row/column code.Итак, как это сделать?

Код должен работать в различных диапазонах, но изначально был жестко запрограммирован для разработки.В openpyxl обработка строк / столбцов более эффективна, чем диапазоны координат, а функциональность диапазона координат постепенно ухудшается.(Код координаты используется только для разработки и будет удален.)

PEP8 выдает continuation line under-indented for visual indent предупреждений.

from __future__ import print_function
from openpyxl import Workbook
from openpyxl.utils import get_column_letter
import openpyxl


def do_widgets(ws, col0, col1):
    """ Process each widget. """
    NO_WDGTS = 5
    ENABLE_START_ROW = 6
    ENABLE_END_ROW = ENABLE_START_ROW + NO_WDGTS - 1
    WDGT_START_ROW = 1
    WDGT_END_ROW = WDGT_START_ROW + NO_WDGTS - 1

    # Coordinate code - delete whole block before implementation
    col_letter0 = get_column_letter(col0)
    col_letter1 = get_column_letter(col1)
    wdgos_range = [(col_letter0 + str(ENABLE_START_ROW) + ":" +
                    col_letter0 + str(ENABLE_END_ROW))]
    wdgos_range.append(col_letter1 + str(WDGT_START_ROW) + ":" +
                       col_letter1 + str(WDGT_END_ROW))
    # Delete
    # wdgos = [cell[1][0].value for cell in zip(ws['B6:B10'], ws['C1:C5'])
    #                                          if cell[0][0].value]
    wdgos = [cell[1][0].value for cell in zip(ws[wdgos_range[0]], ws[wdgos_range[1]])
                                             if cell[0][0].value]

    # Row/column code
    wdgts = [cell[1] for cell in zip([cell.value for col
                     in ws.iter_cols(min_row=ENABLE_START_ROW, min_col=col0,
                                     max_row=ENABLE_END_ROW, max_col=col0)
                     for cell in col],
                     [cell.value for col
                     in ws.iter_cols(min_row=WDGT_START_ROW, min_col=col1,
                                     max_row=WDGT_END_ROW, max_col=col1)
                     for cell in col]) if cell[0]]

    # Use list of enabled widgets
    print("Enable range [0], Widget range [1]")
    print(wdgos_range)
    for wdgo in wdgos:
            print(wdgo)
    print()
    print(wdgts, '\n')


wb = Workbook()
ws = wb.active

rows = [
    ['Number', 'Batch 1', 'Batch 2'],
    [2, 40, 30],
    [3, 40, 25],
    [4, 50, 30],
    [5, 30, 10],
    [0, 0, 0],
    [0, 1, 0],
    [1, 1, 0],
    [0, 0, 1],
    [0, 1, 0],
]

for row in rows:
    ws.append(row)
# Worksheet, enable column, widget column
do_widgets(ws, 2, 3)

Отладочный вывод:

Enable range [0], Widget range [1]
['B6:B10', 'C1:C5']
30
25
10

[30, 25, 10]

1 Ответ

0 голосов
/ 27 мая 2018

возможно, вы могли бы немного упростить это следующим образом:

#define cell "extractor" from given position
def get_cells(row, col):
    for col in ws.iter_cols(min_row = row, min_col = col, max_row = row + NO_WDGTS - 1, max_col = col):
        for cell in col:
            yield cell.value

#use itertools.izip to zip the generators in order to process
#the elements one by one instead of generating them all at once 
wdgts = [cell[1] for cell in itertools.izip(
            get_cells(ENABLE_START_ROW, col0),
            get_cells(WDGT_START_ROW, col1)) if cell[0]]
...