Python, почему цикл for создает два файла docx, когда он должен создать один? - PullRequest
1 голос
/ 21 октября 2019

Код:

from tkinter import *
from docx import Document

root = Tk()



info = ["Option 1", "Option 2", "Option 3"]


vars = []
for idx,i in enumerate(info):
    var = IntVar(value=0)
    vars.append(var)
    lblOption = Label(root,text=i)
    btnYes = Radiobutton(root, text="Yes", variable=var, value=2)
    btnNo = Radiobutton(root, text="No", variable=var, value=1)
    btnNa = Radiobutton(root, text="N/A", variable=var,value=0)
    lblOption.grid(column=4,row=idx, sticky = W)
    btnYes.grid(column=1,row=idx)
    btnNo.grid(column=2,row=idx)
    btnNa.grid(column=3,row=idx)


def save():
    document = Document()

    #add table
    table = document.add_table(1, 4)
    #style table
    table.style = 'Table Grid'

    #populate header row
    heading_cells = table.rows[0].cells
    heading_cells[0].text = "Options"
    heading_cells[1].text = "Yes"
    heading_cells[2].text = "No"
    heading_cells[3].text = "N/a"

    for idx, item in enumerate(vars):
        cells = table.add_row().cells
        cells[0].text = info[idx]  # gets the option name
        val = item.get()  #radiobutton value
        if val == 2:  # checks if yes
            cells[1].text = "*"
            cells[2].text = "not-selected"
            cells[3].text = "not-selected"
        elif val == 1:   # checks if no
            cells[2].text = "*"
            cells[1].text = "not-selected"
            cells[3].text = "not-selected"
        elif val == 0:   # checks if N/A
            cells[3].text = "*"
            cells[1].text = "not-selected"
            cells[2].text = "not-selected"

        fn = document.save("Test.docx")
        for cell in table.columns[2].cells[1:]:
            if cell.text == '*':
                fn = fn = document.save("failed.docx")
                break

        print(fn)

savebtn = Button(root, text = "Save", command = save).grid()

root.mainloop()

Чего я пытаюсь достичь:

Если no был выбран для любого изс помощью переключателей, затем необходимо сохранить документ как Failed.docx. Если каждая опция была выбрана без no's, сохраните файл как Test.docx.

Моя проблема:

Почему у меня последний цикл for и еслиОператор не работает.

Если я выберу несколько no's из радиокнопок и нажму кнопку Сохранить, он создаст мне два файла Test.docx & Failed.docx, тогда как он должен был создать только один файл Failed.docx

Моя цель Моя цель - создать радиокнопки, в зависимости от того, какая опция была выбрана Yes, no & N/A, она сгенерирует файл docx.

Например, еслини один из no не был выбран, затем сгенерируйте файл с именем Test.docx.

Если был выбран хотя бы 1 или более no, то забудьте Test.docx и создайте другое имя файланазывается Failed.docx

Ответы [ 4 ]

2 голосов
/ 21 октября 2019
    fn = document.save("Test.docx")
    for cell in table.columns[2].cells[1:]:
        if cell.text == '*':
            fn = fn = document.save("failed.docx")
            break

Здесь нет условия для первой строки;это достигается независимо от содержания данных. Поэтому Test.docx будет сохраняться каждый раз в цикле, и, следовательно, он будет создаваться до тех пор, пока цикл запускается хотя бы один раз (что будет, поскольку существует более нуля vars, каждый из которых создается из одного из info значения).

Вместо этого: используйте переменную для отслеживания используемого имени файла, а затем выполните сохранение один раз, вне цикла. Фактически, логика тестирования должна также находиться вне основного цикла for, потому что вам нужно искать значения * только один раз, после все значения ячеек были помещенына месте.

# determine all the data that goes in the spreadsheet
for idx, item in enumerate(vars):
    # do a bunch of stuff to set up `cells`
# Now decide whether there was a failure, and choose the docx name
filename = "Test.docx"
for cell in table.columns[2].cells[1:]:
    if cell.text == '*':
        filename = "failed.docx"
# and finally write the spreadsheet
fn = document.save(filename)

Но еще лучше: вы можете исправить имя файла как часть логики заполнения ячеек, когда вы напишите * в столбце сбоя:

filename = "Test.docx"
for idx, item in enumerate(vars):
    # other stuff....
    elif val == 1:
        # if we ever get in this block any time through the loop,
        # the test failed. After all, this is the case where we write the "*"
        # to column 2.
        cells[2].text = "*"
        cells[1].text = "not-selected"
        cells[3].text = "not-selected"
        filename = "failed.docx"
    # other stuff....
# At this point we don't need a separate checking loop; the filename is already set.
fn = document.save(filename)
2 голосов
/ 21 октября 2019
fn = document.save("Test.docx")
for cell in table.columns[2].cells[1:]:
        if cell.text == '*':
            fn = document.save("failed.docx")
            break

Вы сохраняете документ как Test.docx. Затем вы перебираете таблицу. Когда ваше условие if выполнено, вы сохраняете документ как failed.docx, но исходный документ все еще сохраняется как Test.docx - так у вас есть два.

попробуйте что-то вроде:

filename = "Test.docx"
for cell in table.columns[2].cells[1:]:
        if cell.text == '*':
            filename = "failed.docx"
            break
document.save(filename)
2 голосов
/ 21 октября 2019

Вам необходимо проверить, равен ли какой-либо из параметров 1 ('нет'), и изменить имя файла в соответствии с результатом.

    no_in_result = any([var.get() == 1 for var in vars])
    doc_name = "Failed.docx" if no_in_result else "Test.docx"
    fn = fn = document.save(doc_name)
from tkinter import *
from docx import Document

root = Tk()



info = ["Option 1", "Option 2", "Option 3"]


vars = []
for idx,i in enumerate(info):
    var = IntVar(value=0)
    vars.append(var)
    lblOption = Label(root,text=i)
    btnYes = Radiobutton(root, text="Yes", variable=var, value=2)
    btnNo = Radiobutton(root, text="No", variable=var, value=1)
    btnNa = Radiobutton(root, text="N/A", variable=var,value=0)
    lblOption.grid(column=4,row=idx, sticky = W)
    btnYes.grid(column=1,row=idx)
    btnNo.grid(column=2,row=idx)
    btnNa.grid(column=3,row=idx)


def save():
    document = Document()

    #add table
    table = document.add_table(1, 4)
    #style table
    table.style = 'Table Grid'

    #populate header row
    heading_cells = table.rows[0].cells
    heading_cells[0].text = "Options"
    heading_cells[1].text = "Yes"
    heading_cells[2].text = "No"
    heading_cells[3].text = "N/a"

    for idx, item in enumerate(vars):
        cells = table.add_row().cells
        cells[0].text = info[idx]  # gets the option name
        val = item.get()  #radiobutton value
        if val == 2:  # checks if yes
            cells[1].text = "*"
            cells[2].text = "not-selected"
            cells[3].text = "not-selected"
        elif val == 1:   # checks if no
            cells[2].text = "*"
            cells[1].text = "not-selected"
            cells[3].text = "not-selected"
        elif val == 0:   # checks if N/A
            cells[3].text = "*"
            cells[1].text = "not-selected"
            cells[2].text = "not-selected"

    no_in_result = any([var.get() == 1 for var in vars])
    doc_name = "Failed.docx" if no_in_result else "Test.docx"
    fn = fn = document.save(doc_name)
    print(fn)

savebtn = Button(root, text = "Save", command = save).grid()

root.mainloop()
2 голосов
/ 21 октября 2019

это строка fn = document.save("Test.docx"), которая каждый раз создает Test.docx. Вот способ решения проблемы:

from tkinter import *
from docx import Document

root = Tk()



info = ["Option 1", "Option 2", "Option 3"]


vars = []
for idx,i in enumerate(info):
    var = IntVar(value=0)
    vars.append(var)
    lblOption = Label(root,text=i)
    btnYes = Radiobutton(root, text="Yes", variable=var, value=2)
    btnNo = Radiobutton(root, text="No", variable=var, value=1)
    btnNa = Radiobutton(root, text="N/A", variable=var,value=0)
    lblOption.grid(column=4,row=idx, sticky = W)
    btnYes.grid(column=1,row=idx)
    btnNo.grid(column=2,row=idx)
    btnNa.grid(column=3,row=idx)


def save():
    document = Document()

    #add table
    table = document.add_table(1, 4)
    #style table
    table.style = 'Table Grid'

    #populate header row
    heading_cells = table.rows[0].cells
    heading_cells[0].text = "Options"
    heading_cells[1].text = "Yes"
    heading_cells[2].text = "No"
    heading_cells[3].text = "N/a"

    yes_flag = True

    for idx, item in enumerate(vars):
        cells = table.add_row().cells
        cells[0].text = info[idx]  # gets the option name
        val = item.get()  #radiobutton value
        if val == 2:  # checks if yes
            cells[1].text = "*"
            cells[2].text = "not-selected"
            cells[3].text = "not-selected"
        elif val == 1:   # checks if no
            cells[2].text = "*"
            cells[1].text = "not-selected"
            cells[3].text = "not-selected"
            yes_flag = False
        elif val == 0:   # checks if N/A
            cells[3].text = "*"
            cells[1].text = "not-selected"
            cells[2].text = "not-selected"
            yes_flag = False

        if yes_flag:
            fn = document.save("Test.docx")
        for cell in table.columns[2].cells[1:]:
            if cell.text == '*':
                fn = fn = document.save("failed.docx")
                break

        print(fn)

savebtn = Button(root, text = "Save", command = save).grid()

root.mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...