<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def rn(shape, dtype=None, impl='numpy', **kwargs):
 """Return a space of real tensors. Parameters shape : positive int or sequence of positive ints Number of entries per axis for elements in this space. A single integer results in a space with 1 axis. dtype : optional Data type of each element. Can be provided in any way the `numpy.dtype` function understands, e.g. as built-in type or as a string. Only real floating-point data types are allowed. For ``None``, the `TensorSpace.default_dtype` of the created space is used in the form ``default_dtype(RealNumbers())``. impl : str, optional Impmlementation back-end for the space. See `odl.space.entry_points.tensor_space_impl_names` for available options. kwargs : Extra keyword arguments passed to the space constructor. Returns ------- real_space : `TensorSpace` Examples -------- Space of real 3-tuples with ``float32`` entries: rn(3, dtype='float32') Real 2x3 tensors with ``float32`` entries: rn((2, 3), dtype='float32') The default data type depends on the implementation. For ``impl='numpy'``, it is ``'float64'``: rn((2, 3)) dtype('float64') See Also -------- tensor_space : Space of tensors with arbitrary scalar data type. cn : Complex tensor space. """

    rn_cls = tensor_space_impl(impl)

    if dtype is None:
        dtype = rn_cls.default_dtype(RealNumbers())

    # Use args by keyword since the constructor may take other arguments
    # by position
    rn = rn_cls(shape=shape, dtype=dtype, **kwargs)
    if not rn.is_real:
        raise ValueError('data type {!r} not a real floating-point type.'
                         ''.format(dtype))
    return rn