Module for useful functions that aren’t available elsewhere and don’t fit with Pymagicc.

When we say “available elsewhere and don’t fit with Pymagicc” we mean that they are not available to be included as a dependency of Pymagicc nor are they really/solely related to running MAGICC. A good test of what belongs here is anything for which one thinks, “I need this, I can’t find it anywhere else and I would probably use it again in another project”. One day we may move all these utility functions to another project to make it easier for ourselves and others to re-use them.

pymagicc.utils.apply_string_substitutions(inputs, substitutions, inverse=False, case_insensitive=False, unused_substitutions='ignore')[source]

Apply a number of substitutions to a string(s).

The substitutions are applied effectively all at once. This means that conflicting substitutions don’t interact. Where substitutions are conflicting, the one which is longer takes precedance. This is confusing so we recommend that you look at the examples.

  • inputs (str, list of str) – The string(s) to which we want to apply the substitutions.

  • substitutions (dict) – The substitutions we wish to make. The keys are the strings we wish to substitute, the values are the strings which we want to appear in the output strings.

  • inverse (bool) – If True, do the substitutions the other way around i.e. use the keys as the strings we want to appear in the output strings and the values as the strings we wish to substitute.

  • case_insensitive (bool) – If True, the substitutions will be made in a case insensitive way.

  • unused_substitutions ({"ignore", "warn", "raise"}, default ignore) – Behaviour when one or more of the inputs does not have a corresponding substitution. If “ignore”, nothing happens. If “warn”, a warning is issued. If “raise”, an error is raised. See the examples.


The input with substitutions performed.

Return type



>>> apply_string_substitutions("Hello JimBob", {"Jim": "Bob"})
'Hello BobBob'
>>> apply_string_substitutions("Hello JimBob", {"Jim": "Bob"}, inverse=True)
'Hello JimJim'
>>> apply_string_substitutions(["Hello JimBob", "Jim says, 'Hi Bob'"], {"Jim": "Bob"})
['Hello BobBob', "Bob says, 'Hi Bob'"]
>>> apply_string_substitutions(["Hello JimBob", "Jim says, 'Hi Bob'"], {"Jim": "Bob"}, inverse=True)
['Hello JimJim', "Jim says, 'Hi Jim'"]
>>> apply_string_substitutions("Muttons Butter", {"M": "B", "Button": "Zip"})
'Buttons Butter'
# Substitutions don't cascade. If they did, Muttons would become Buttons, then the
# substitutions "Button" --> "Zip" would be applied and we would end up with
# "Zips Butter".
>>> apply_string_substitutions("Muttons Butter", {"Mutton": "Gutter", "tt": "zz"})
'Gutters Buzzer'
# Longer substitutions take precedent. Hence Mutton becomes Gutter, not Muzzon.
>>> apply_string_substitutions("Butter", {"buTTer": "Gutter"}, case_insensitive=True)
>>> apply_string_substitutions("Butter", {"teeth": "tooth"})
>>> apply_string_substitutions("Butter", {"teeth": "tooth"}, unused_substitutions="ignore")
>>> apply_string_substitutions("Butter", {"teeth": "tooth"}, unused_substitutions="warn")
...pymagicc/ UserWarning: No substitution available for {'Butter'} warnings.warn(msg)
>>> apply_string_substitutions("Butter", {"teeth": "tooth"}, unused_substitutions="raise")
ValueError: No substitution available for {'Butter'}

Return a timestamp with current date and time.