I have the following code I wrote in python, but I want to make it easier to maintain.
from tkinter import *
from tkinter import filedialog
import os
from docx import document
def replace_text(file_path, b1o, b1a, b1p, b1e):
document = document(file_path)
for paragraph in document.paragraphs:
if 'B1O' in paragraph.text:
paragraph.text = paragraph.text.replace('B1O', b1o)
if 'B1A' in paragraph.text:
paragraph.text = paragraph.text.replace('B1A', b1a)
if 'B1P' in paragraph.text:
paragraph.text = paragraph.text.replace('B1P', b1p)
if 'B1E' in paragraph.text:
paragraph.text = paragraph.text.replace('B1E', b1e)
return document
How can I combine the if statements and make them easier to manage?
I’ve looked at How to consolidate if / elif statements in Python, but I’m unsure how to utilize the solution with this particular use case.
Thanks for any input!
EDIT: Here is the rest of the program snipped to include only the parts mentioned here.
def generate_file():
# Open a file dialog to select a template file
root = Tk()
root.withdraw()
file_path = filedialog.askopenfilename(
title="Select a template file",
filetypes=[("Word files", "*.docx")],
initialdir=r"C://desktop/Templates"
)
# Get user input for variables
b1o = input("Enter the name of the owner: ")
b1a = input("Enter the address: ")
b1p = input("Enter the phone number: ")
b1e = input("Enter the email address: ")
# Replace placeholders with user input
document = replace_text(file_path, b1o, b1a, b1p, b1e)
# Open a file dialog to select a folder to save the new file
folder_path = filedialog.askdirectory(title="Select a folder to save the new file")
file_name = os.path.splitext(os.path.basename(file_path))[0] + "_" + b1p + "_" + b1o + ".docx"
file_path = os.path.join(folder_path, file_name)
# Save the modified document as a new file
document.save(file_path)
print("File saved at:", file_path)
root = Tk()
root.title("Generate New Document")
# Create a button to generate a new file
generate_button = Button(root, text="Select Template and
Generate", command=generate_file)
generate_button.pack()
root.mainloop()
>Solution :
Because your code isn’t a Minimal Reproducible Example we can’t test our answers, but an efficient fix might look something like:
import re
import functools
def replace_text(file_path, b1o, b1a, b1p, b1e):
document = document(file_path)
replacements = { 'B1O': b1o, 'B1A': b1a, 'B1P': b1p, 'B1E': b1e }
subFn = functools.partial(
re.sub,
'|'.join(replacements.keys()),
lambda match: replacements[match.group(0)]
)
for paragraph in document.paragraphs:
paragraph.text = subFn(paragraph.text)
return document
Using re.sub()
lets us search for all four strings in a single pass, instead of needing to search for them one after the other.