<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _infer_coords_and_dims(shape, coords, dims):
 """All the logic for creating a new DataArray"""


    if (coords is not None and not utils.is_dict_like(coords) and
            len(coords) != len(shape)):
        raise ValueError('coords is not dict-like, but it has %s items, '
                         'which does not match the %s dimensions of the '
                         'data' % (len(coords), len(shape)))

    if isinstance(dims, str):
        dims = (dims,)

    if dims is None:
        dims = ['dim_%s' % n for n in range(len(shape))]
        if coords is not None and len(coords) == len(shape):
            # try to infer dimensions from coords
            if utils.is_dict_like(coords):
                # deprecated in GH993, removed in GH1539
                raise ValueError('inferring DataArray dimensions from '
                                 'dictionary like ``coords`` is no longer '
                                 'supported. Use an explicit list of '
                                 '``dims`` instead.')
            for n, (dim, coord) in enumerate(zip(dims, coords)):
                coord = as_variable(coord,
                                    name=dims[n]).to_index_variable()
                dims[n] = coord.name
        dims = tuple(dims)
    else:
        for d in dims:
            if not isinstance(d, str):
                raise TypeError('dimension %s is not a string' % d)

    new_coords = OrderedDict()

    if utils.is_dict_like(coords):
        for k, v in coords.items():
            new_coords[k] = as_variable(v, name=k)
    elif coords is not None:
        for dim, coord in zip(dims, coords):
            var = as_variable(coord, name=dim)
            var.dims = (dim,)
            new_coords[dim] = var

    sizes = dict(zip(dims, shape))
    for k, v in new_coords.items():
        if any(d not in dims for d in v.dims):
            raise ValueError('coordinate %s has dimensions %s, but these '
                             'are not a subset of the DataArray '
                             'dimensions %s' % (k, v.dims, dims))

        for d, s in zip(v.dims, v.shape):
            if s != sizes[d]:
                raise ValueError('conflicting sizes for dimension %r: '
                                 'length %s on the data but length %s on '
                                 'coordinate %r' % (d, sizes[d], s, k))

        if k in sizes and v.shape != (sizes[k],):
            raise ValueError('coordinate %r is a DataArray dimension, but '
                             'it has shape %r rather than expected shape %r '
                             'matching the dimension size'
                             % (k, v.shape, (sizes[k],)))

    assert_unique_multiindex_level_names(new_coords)

    return new_coords, dims