<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def deprecate(warning, date=None, log=None):
 """Add a deprecation warning the first time the function is used. The date, which is a string in semi-ISO8660 format indicate the year-month that the function is officially going to be removed. usage: @deprecate('use core/fetch/add_source() instead', '2017-04') And it then prints to the log ONCE that the function is deprecated. The reason for passing the logging function (log) is so that hookenv.log can be used for a charm if needed. :param warning: String to indicat where it has moved ot. :param date: optional sting, in YYYY-MM format to indicate when the function will definitely (probably) be removed. :param log: The log function to call to log. If not, logs to stdout """

    def wrap(f):

        @functools.wraps(f)
        def wrapped_f(*args, **kwargs):
            try:
                module = inspect.getmodule(f)
                file = inspect.getsourcefile(f)
                lines = inspect.getsourcelines(f)
                f_name = "{}-{}-{}..{}-{}".format(
                    module.__name__, file, lines[0], lines[-1], f.__name__)
            except (IOError, TypeError):
                # assume it was local, so just use the name of the function
                f_name = f.__name__
            if f_name not in __deprecated_functions:
                __deprecated_functions[f_name] = True
                s = "DEPRECATION WARNING: Function {} is being removed".format(
                    f.__name__)
                if date:
                    s = "{} on/around {}".format(s, date)
                if warning:
                    s = "{} : {}".format(s, warning)
                if log:
                    log(s)
                else:
                    print(s)
            return f(*args, **kwargs)
        return wrapped_f
    return wrap