Generate a text file according to the successful steps. - Possible improvement of the code or other way of doing it?

Viewed 29

I would like to keep track of the steps taken by the program in a text report file. Each step in the code returns a dataframe and there is a dependency between tasks (task n cannot be executed if task n-1 had found nothing).

My programme looks like this:

(kind of pseudo code)

import pandas as pd

step_1 = find_stuff()
if not step_1.empty:
    step_2 = find_new_stuff()   
    if not step_2.empty:
        step_3 = find_new_stuff_again()        
        if not step_3.empty: 
            report (step_1, step_2, step_3)           
        else: 
            report (step_1, step_2, step_3=pd.DataFrame())           
    else:
        report (step_1, step_2=pd.DataFrame(), step_3=pd.DataFrame())     
else:
    report (step_1=pd.DataFrame(), step_2=pd.DataFrame(), step_3=pd.DataFrame())
    


def report (step_1, step_2, step_3) :
    report_file = open("report.txt", "a")
    if not step_1.empty:
        report_file.write(f'Here what was found for step 1 \n : { step_1} \n')
        if not step_2.empty:
            report_file.write(f'Here what was found for step 2 \n : { step_2} \n') 
            if not step_3.empty:
                report_file.write(f'Here what was found for step 3 \n : { step_3} \n')     
    else: 
        report_file.write('Nothing was found \n')

This way of doing things is very basic but does what I ask it to do. Though, I was wondering if there was a way to avoid/reduce all these "if" or an alternative way to generate this kind of report?

2 Answers

In principle, I think your code is readable and gets the job done. However, if you have a lot of steps, you might want to iterate over them.

Here is an example:

import pandas as pd

def report(steps):
    report_file = open("report.txt", "a")

    for i, s in enumerate(steps):
        report_file.write(f"Here what was found for step {i+1} \n : { s} \n")

steps = []
find_functions = [find_stuff, find_new_stuff, find_new_stuff_again]

for f in find_functions:
    found_stuff = f()
    if found_stuff.empty:
        break
    steps.append(found_stuff)

report(steps)

Also, mind that you are currently opening your report in "a" mode, so it will append results if you rerun the code.

My answer is similar to @Nik's so that you need to iterate over some functions but I added it to a class so you can have the state together with the functions in the same scope. I also changed you file opening to use with as it is considered the safe way to handle files:

class StepFailedException(Exception): pass

class StuffFinder:
    def __init__(self):
        self.findings = []
        
    def find_stuff_1(self):
        stuff = None
        # find stuff
        if stuff.empty:
            raise StepFailedException
        self.findings.append(stuff)
        
    def find_stuff_2(self):
        stuff = None
        # find stuff
        if stuff.empty:
            raise StepFailedException
        self.findings.append(stuff)
        
    def find_stuff_3(self):
        stuff = None
        # find stuff
        if stuff.empty:
            raise StepFailedException
        self.findings.append(stuff)
        
    def report(self):
        if self.findings:
            with open("report.txt", "a") as report_file:
                for i,stuff in enumerate(self.findings):
                    report_file.write(f'Here what was found for step {i+1} \n : { stuff } \n')
                    
    def clear(self):
        self.findings.clear()
                    
    def find_stuff(self):
        self.clear()
        try:
            self.find_stuff_1()
            self.find_stuff_2()
            self.find_stuff_3()
        except StepFailedException as e:
            # handle exception if necessary
            pass
        self.report()

sf = StuffFinder() # you could add some initial values as argument to the constructor
sf.find_stuff()

# OR go step by step

sf.clear()
sf.find_stuff_1()
# sf.find_stuff_2() let's skip this one
sf.find_stuff_3()
sf.report()
Related