Let's say I have a function that returns a dataset. First it tries to read it and if that fails it is requested from an API and then written:
def get_dataset():
try:
df = pd.read_csv('dataset.csv')
except FileNotFoundError:
df = pd.DataFrame(api.get_dataset())
df.to_csv('dataset.csv')
return df
Now we may want to force making the request and update the CSV file, so we pass a flag. In order to be more concise with the code, we can use a cheap trick to force the execution of the except block:
def get_dataset(force_udpate=False):
try:
if force_update:
raise FileNotFoundError
df = pd.read_csv('dataset.csv')
except FileNotFoundError:
df = pd.DataFrame(api.get_dataset())
df.to_csv('dataset.csv')
return df
Of course this looks bad, because a FileNotFoundError
is not really applicable. But if we didn't do this we would either have to break the DRY principle:
def get_dataset(force_update=False):
if force_update:
df = pd.DataFrame(api.get_dataset())
df.to_csv('dataset.csv')
return df
try:
df = pd.read_csv('dataset.csv')
except FileNotFoundError:
df = pd.DataFrame(api.get_dataset())
df.to_csv('dataset.csv')
return df
Or introduce a local function, dirtying the whole function a bit:
def get_dataset(force_update=False):
def request_and_write():
d = pd.DataFrame(api.get_dataset())
d.to_csv('dataset.csv')
return d
if force_udpate:
return request_and_write()
try:
df = pd.read_csv('dataset.csv')
except FileNotFoundError:
df = request_and_write()
return df
Is that questionable practice acceptable for the sake of code simplicity and clarity?