<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def fillna(data, other, join="left", dataset_join="left"):
 """Fill missing values in this object with data from the other object. Follows normal broadcasting and alignment rules. Parameters join : {'outer', 'inner', 'left', 'right'}, optional Method for joining the indexes of the passed objects along each dimension - 'outer': use the union of object indexes - 'inner': use the intersection of object indexes - 'left': use indexes from the first object with each dimension - 'right': use indexes from the last object with each dimension - 'exact': raise `ValueError` instead of aligning when indexes to be aligned are not equal dataset_join : {'outer', 'inner', 'left', 'right'}, optional Method for joining variables of Dataset objects with mismatched data variables. - 'outer': take variables from both Dataset objects - 'inner': take only overlapped variables - 'left': take only variables from the first object - 'right': take only variables from the last object """

    from .computation import apply_ufunc

    return apply_ufunc(duck_array_ops.fillna, data, other,
                       join=join,
                       dask="allowed",
                       dataset_join=dataset_join,
                       dataset_fill_value=np.nan,
                       keep_attrs=True)