AarCee
AarCee

Reputation: 863

Coding design for a (standard?) issue

Seems like a standard enough problem to warrant a standard design in the solution:

Say I want to write x+2 (or less) strings in a file. x strings make up the content of a section and the two strings make a kind of a header and footer for that section. The catch is that I would not write the header/footer strings if there are no strings in the content. Furthermore, these x strings are written from disparate places in the code. So the current flow is:

  1. write header string
  2. write content strings
  3. write footer string

This leads to the header/footer strings being written even if the content is empty, and I have to address that, i.e. not writing the header/footer strings in this case.

The solution that I can think of is writing the header string before the first content string that is being written (implemented by funnelling each content string write with a header string write, with a boolean flag preventing multiple header string writes), and then writing the footer string only if the header string has been written (governed by a boolean flag).

This is the top level gist of it, just wondering if there are standard approaches available for cases like these.

Thanks!

Upvotes: 0

Views: 69

Answers (1)

paxdiablo
paxdiablo

Reputation: 882336

There are a number of solutions to this:

  • Write the header and data lines to an in-memory cache and output them at the time you try to write the footer (but only if there are data lines, otherwise output nothing).
  • Same thing but using a temporary file for the data cache in case it's too big.
  • Remember the header and whether or not you've output it.

Since the first two solutions involve inefficiencies (caching possibly large amounts of data, or using relatively slow external storage), I'll concentrate on the latter. See the note at the bottom on how to do the caching (a).

The approach which doesn't require caching the data is to just have an indicator as to whether or not you've written the header. Before each data line, output the header (and set the flag) only if the flag is not yet set. You can also use this flag to control the footer (if the header hasn't been output, neither should the footer be):

def outHeader (str):
    headerText = str
    headerSent = false

def outdata (str):
    if not headerSent:
        write headerText
        headerSent = true
    write str

def outFooter (str):
    if headerSent:
        write str

This solution is perhaps much simpler in terms of no data caching required.


(a) If you did want to go with the caching solution (despite the advice that it's a sub-optimal solution), the following pseudo-code shows how it could be done:

def outHeader (str):
    cachedHeader = str
    cachedData = ""

def outdata (str):
    cachedData = cachedData + str + "\n"

def outFooter (str):
    if cachedData != "":
        write cachedHeader
        write cachedData
        write str

The only difference between that in-memory cache and a file-based cache is:

  • creating an empty temporary file and setting lineCount to 0 where you currently create cachedData in outHeader().
  • sending str to the temporary file and incrementing lineCount in outData().
  • using lineCount to decide if there's cached data in outFooter and reading the lines back from the temporary file for output as data.

Upvotes: 2

Related Questions