I'm writing a function that needs to get libraries (files) for a Company
from a folder path. Thereafter it needs to install those in a repository. While doing this I need to inform the user what is happening. Below is the code.
def run(self):
self.__get_libraries(self.__companies)
for company in self.__companies:
self.__install_libraries(company)
return True, ""
def __get_libraries(self, companies):
output.printnlog("Searching library files for:")
total_libraries = 0
for company in companies:
output.printnlog("- {} in {}".format(company.name, company.libraries_folder_path))
company.get_library_files()
total_libraries += len(company.get_library_files())
output.printnlog("Libraries found:", pre_empty=True)
output.printnlog("- All companies: {}".format(total_libraries))
reporter.setelement(self.__xml_total_libraries, total_libraries)
for company in companies:
output.printnlog("- {}: {}".format(company.name, len(company.get_library_files())))
reporter.setelement(company.xml_element, company.get_dict())
def __install_libraries(self, company):
output.printnlog("Installing library files for {} from {}."
.format(company.name, company.libraries_folder_path), pre_empty=True)
repository = librarymanager.repositories[0]
libraries = company.get_library_files()
width = int(math.ceil(math.log10(len(libraries))))
index = 1
for library in libraries:
output.printnlog("Installing library {} of {}: {}"
.format(str(index).rjust(width), len(libraries),
os.path.basename(library)))
install_start_time = datetime.now()
librarymanager.install_library(library, repository, True)
elapsed_time = output.log_elapsedtime("Library {} of {} installed within {}."
.format(str(index).rjust(width), len(libraries),
"{}"), install_start_time)
reporter.setelement(company.xml_element.elrecords, {
"record": {"nr": index, "library": os.path.basename(library),
"elapsed_time": elapsed_time}})
index += 1
Now, everything is working fine but I have the feeling that the code that is actually doing something is lost by the code to inform the user. If I'd stip all the informative stuff, I end up with only this:
def run(self):
self.__get_libraries(self.__companies)
for company in self.__companies:
self.__install_libraries(company)
return True, ""
def __get_libraries(self, companies):
for company in companies:
company.get_library_files()
def __install_libraries(self, company):
repository = librarymanager.repositories[0]
libraries = company.get_library_files()
for library in libraries:
librarymanager.install_library(library, repository, True)
Is there a good compromise to make between both versions of code? I need the information stuff as a requirement but is it possible to "hide" it from the actual execution code?
-
Have you considered following the traditional Unix approach to only tell the user about things that are going wrong? If a utility works as desired, there should be no output at all (unless of course the purpose of the utility is to output something).Jörg W Mittag– Jörg W Mittag2021年10月08日 11:59:31 +00:00Commented Oct 8, 2021 at 11:59
1 Answer 1
I'm very much a beginner with Python, so the following syntax is likely nonsense, but hopefully it demonstrates my point.
Focusing on __install_libraries
by way of example, I'd have another class, module or whatever that handled the messaging and would anticipate ending up with compromise code something like:
def __install_libraries(self, company):
user_notifier = new UserNotifier(company)
user_notifier.notify_installing_libraries()
repository = librarymanager.repositories[0]
libraries = company.get_library_files()
for library in libraries:
user_notifier.notify_installing_library(library)
librarymanager.install_library(library, repository, True)
user_notifier.notify_installed_library(library)
Then all the code that calculates width
, is used to format the messages and increments index
gets moved into the UserNotifier
module/class.
Your code then focuses on installing the libraries and delegates reporting to another separate piece of code, which is what I generally see as the best compromise in these situations.