<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def get_param_bounds_from_config(cp, section, tag, param):
 """Gets bounds for the given parameter from a section in a config file. Minimum and maximum values for bounds are specified by adding `min-{param}` and `max-{param}` options, where `{param}` is the name of the parameter. The types of boundary (open, closed, or reflected) to create may also be specified by adding options `btype-min-{param}` and `btype-max-{param}`. Cyclic conditions can be adding option `cyclic-{param}`. If no `btype` arguments are provided, the left bound will be closed and the right open. For example, the following will create right-open bounds for parameter `foo`: .. code-block:: ini [{section}-{tag}] min-foo = -1 max-foo = 1 This would make the boundaries cyclic: .. code-block:: ini [{section}-{tag}] min-foo = -1 max-foo = 1 cyclic-foo = For more details on boundary types and their meaning, see `boundaries.Bounds`. If the parameter is not found in the section will just return None (in this case, all `btype` and `cyclic` arguments are ignored for that parameter). If bounds are specified, both a minimum and maximum must be provided, else a Value or Type Error will be raised. Parameters cp : ConfigParser instance The config file. section : str The name of the section. tag : str Any tag in the section name. The full section name searched for in the config file is `{section}(-{tag})`. param : str The name of the parameter to retrieve bounds for. Returns ------- bounds : {Bounds instance | None} If bounds were provided, a `boundaries.Bounds` instance representing the bounds. Otherwise, `None`. """

    try:
        minbnd = float(cp.get_opt_tag(section, 'min-'+param, tag))
    except Error:
        minbnd = None
    try:
        maxbnd = float(cp.get_opt_tag(section, 'max-'+param, tag))
    except Error:
        maxbnd = None
    if minbnd is None and maxbnd is None:
        bnds = None
    elif minbnd is None or maxbnd is None:
        raise ValueError("if specifying bounds for %s, " %(param) +
            "you must provide both a minimum and a maximum")
    else:
        bndargs = {'min_bound': minbnd, 'max_bound': maxbnd}
        # try to get  any other conditions, if provided
        try:
            minbtype = cp.get_opt_tag(section, 'btype-min-{}'.format(param),
                                      tag)
        except Error:
            minbtype = 'closed'
        try:
            maxbtype = cp.get_opt_tag(section, 'btype-max-{}'.format(param),
                                      tag)
        except Error:
            maxbtype = 'open'
        bndargs.update({'btype_min': minbtype, 'btype_max': maxbtype})
        cyclic = cp.has_option_tag(section, 'cyclic-{}'.format(param), tag)
        bndargs.update({'cyclic': cyclic})
        bnds = boundaries.Bounds(**bndargs)
    return bnds